我正在尝试使用AWS KMS客户管理密钥在NodeJS中使用ES 256算法创建JWT签名。
使用AWS KMS和加密签名算法ECDSA_SHA_256创建的签名不是JWT接受的R||S格式。根据AWS文档,签名将采用DER编码的ANS X9.62-2005格式(https://docs.aws.amazon.com/kms/latest/APIReference/API_Sign.html#API_Sign_ResponseSyntax)。
我尝试将AWS KMS Sign转换为JWT R||S格式使用下面的代码在NodeJS与ans 1 js(https://www.npmjs.com/package/asn1js),但R和S的长度是不一致的32 + 32,而它的变化33的大部分时间。
function toArrayBuffer(buffer) {
const ab = new ArrayBuffer(buffer.length);
const view = new Uint8Array(ab);
for (let i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return ab;
}
//call this with your signature buffer
function parseBERSignature(sig) {
const { result } = asn1js.fromBER(toArrayBuffer(sig));
const part1 = result.valueBlock.value[0];
const part2 = result.valueBlock.value[1];
let r = Buffer.from(part1.valueBlock.valueHex);
let s = Buffer.from(part2.valueBlock.valueHex);
console.log("R value", r);
console.log("S value", s);
console.log("R value", r.toString('base64'));
console.log("S value", s.toString('base64'));
console.log("R length", r.length);
console.log("S length", s.length);
return base64url.fromBase64(Buffer.concat([r, s]).toString('base64'));
}
签名创建的完整代码:
const base64url = require('base64url')
const AWS = require('aws-sdk');
const kms = new AWS.KMS();
const asn1js = require('asn1js')
const keyid = "9001e08c-b7bc-4f53-9eca-ec034904cdd5";
const header = {
"typ": "JWT",
"alg": "ES256",
"kid": keyid
}
const payload = {
"sub": "name",
"status": "valid",
"aud": "name"
}
exports.handler = async function (event, context, callback) {
console.log("Hello, new World");
payload.iat = Math.floor(Date.now() / 1000);
console.log("header", header);
console.log("payload", payload);
const jwtHeader = base64url(JSON.stringify(header));
const jwtPayload = base64url(JSON.stringify(payload));
console.log("jwtHeader", jwtHeader);
console.log("jwtPayload", jwtPayload);
const message = Buffer.from(jwtHeader + "." + jwtPayload);
const messageDigest = createHash(message);
let kmsResponse = await kms.sign({
Message: message,
KeyId: keyid,
SigningAlgorithm: 'ECDSA_SHA_256',
MessageType: 'RAW'
}).promise();
console.log("Signature RAW", kmsResponse.Signature);
console.log("Signature String", kmsResponse.Signature.toString());
console.log("Signature base64", kmsResponse.Signature.toString('base64'));
let response = parseBERSignature(kmsResponse.Signature);
console.log("response", response);
return jwtHeader + "." + jwtPayload + "." + response;
}
将DER编码的ANS格式转换为R的任何NodeJs Javascript实现||S格式base64 url编码?
2条答案
按热度按时间nqwrtyyt1#
将DER编码的ANS格式转换为R的任何NodeJs Javascript实现||S格式base64url编码?
是的,ecdsa-sig-formatter将帮助您在格式之间来回转换签名。
ql3eal8s2#
🥳最后,使用ES256的AWS KMS工作解决方案
在解决这个问题后,我找到了一个适用于NodeJs的好解决方案。
前面提到的包' ecdsa-sig-formatter '无法用于EllipticCurve算法签名格式设置。
我将代码从Typescript转换为一个可工作的Javascript文件。以下代码改编自node-ecdsa-sig-formatter,并由stacks-network/jsontokens-js修复
在使用AWS KMS(使用EC256)签名后,您需要做的是将签名从DERtoJOSE转换为: