NodeJS AWS KMS 签署和验证令牌
NodeJS AWS KMS sign and verify token
我正在尝试创建 JWT,然后使用 AWS KMS 节点对其进行验证 API。
下面是我的代码,代表了我对 AWS 文档的理解。
但是调用 KMS 验证会抛出 KMSInvalidSignatureException
process.env.AWS_REGION = '...';
process.env.AWS_ACCOUNT_ID = '...';
process.env.AWS_PROFILE = '...';
process.env.KEY_ID = '...id of RSA 2048 bytes key stored in AWS KMS...';
const aws = require('aws-sdk');
const kms = new aws.KMS();
const base64url = require('base64url');
async function createToken() {
const iat = Math.floor(Date.now() / 1000);
const tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1)
const exp = Math.floor(tomorrow.getTime() / 1000);
const header = base64url.encode(JSON.stringify({
alg: 'RS256',
typ: 'JWT'
}));
const payload = base64url.encode(JSON.stringify({
iat,
exp,
code: '123'
}));
const message = Buffer.from(`${header}.${payload}`);
const signResponse = await kms.sign({
KeyId: process.env.KEY_ID,
Message: message,
MessageType: 'RAW',
SigningAlgorithm: 'RSASSA_PKCS1_V1_5_SHA_256'
}).promise();
const signature = signResponse.Signature.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
return `${header}.${payload}.${signature}`;
}
async function verifyToken(token) {
const [header, payload, signature] = token.split('.');
const message = Buffer.from(`${header}.${payload}`);
return await kms.verify({
KeyId: process.env.KEY_ID,
Message: message,
MessageType: 'RAW',
Signature: signature,
SigningAlgorithm: 'RSASSA_PKCS1_V1_5_SHA_256'
}).promise();
}
async function main() {
const token = await createToken();
const verification = await verifyToken(token);
console.log(verification);
}
main();
我做错了什么?
至少对于 aws-sdk 的 V3,verify
期望 Signature
是 Buffer/Uint8Array。
可能修复了 verifyToken 函数(也删除了过时的 async/await
):
function verifyToken(token) {
const [header, payload, signature] = token.split('.');
const message = Buffer.from(`${header}.${payload}`);
return kms.verify({
KeyId: process.env.KEY_ID,
Message: message,
MessageType: 'RAW',
Signature: Buffer.from(signature, 'base64'),
SigningAlgorithm: 'RSASSA_PKCS1_V1_5_SHA_256'
}).promise();
}
我正在尝试创建 JWT,然后使用 AWS KMS 节点对其进行验证 API。 下面是我的代码,代表了我对 AWS 文档的理解。 但是调用 KMS 验证会抛出 KMSInvalidSignatureException
process.env.AWS_REGION = '...';
process.env.AWS_ACCOUNT_ID = '...';
process.env.AWS_PROFILE = '...';
process.env.KEY_ID = '...id of RSA 2048 bytes key stored in AWS KMS...';
const aws = require('aws-sdk');
const kms = new aws.KMS();
const base64url = require('base64url');
async function createToken() {
const iat = Math.floor(Date.now() / 1000);
const tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1)
const exp = Math.floor(tomorrow.getTime() / 1000);
const header = base64url.encode(JSON.stringify({
alg: 'RS256',
typ: 'JWT'
}));
const payload = base64url.encode(JSON.stringify({
iat,
exp,
code: '123'
}));
const message = Buffer.from(`${header}.${payload}`);
const signResponse = await kms.sign({
KeyId: process.env.KEY_ID,
Message: message,
MessageType: 'RAW',
SigningAlgorithm: 'RSASSA_PKCS1_V1_5_SHA_256'
}).promise();
const signature = signResponse.Signature.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
return `${header}.${payload}.${signature}`;
}
async function verifyToken(token) {
const [header, payload, signature] = token.split('.');
const message = Buffer.from(`${header}.${payload}`);
return await kms.verify({
KeyId: process.env.KEY_ID,
Message: message,
MessageType: 'RAW',
Signature: signature,
SigningAlgorithm: 'RSASSA_PKCS1_V1_5_SHA_256'
}).promise();
}
async function main() {
const token = await createToken();
const verification = await verifyToken(token);
console.log(verification);
}
main();
我做错了什么?
至少对于 aws-sdk 的 V3,verify
期望 Signature
是 Buffer/Uint8Array。
可能修复了 verifyToken 函数(也删除了过时的 async/await
):
function verifyToken(token) {
const [header, payload, signature] = token.split('.');
const message = Buffer.from(`${header}.${payload}`);
return kms.verify({
KeyId: process.env.KEY_ID,
Message: message,
MessageType: 'RAW',
Signature: Buffer.from(signature, 'base64'),
SigningAlgorithm: 'RSASSA_PKCS1_V1_5_SHA_256'
}).promise();
}