【发布时间】:2021-12-12 23:33:50
【问题描述】:
我已经能够在jwt.io 的 Web UI 上验证 GCP ID 令牌,但我很难在 JS 代码中复制它。
我同时使用了jose 和jsrsasign 库,但收效甚微。
一些我自己的代码来了解基础
function decodeJWT(jwtString: string) {
const jwt = jwtString.match(
/(?<header>[^.]+)\.(?<payload>[^.]+)\.(?<signature>[^.]+)/
).groups;
// For simplicity trust that the urlBase64toStr function works
// The parsed JWT is identical to what I see on jwt.io
jwt.header = JSON.parse(urlBase64toStr(jwt.header));
jwt.payload = JSON.parse(urlBase64toStr(jwt.payload));
return jwt;
}
const jwt = decodeJWT('<....JWT string here......>')
const encoder = new TextEncoder();
const byteArrays = {
signature: encoder.encode(jwt.signature),
body: encoder.encode(
JSON.stringify(jwt.header) + "." + JSON.stringify(jwt.payload)
)
};
// Google's public certs at https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com
const cert = '-----BEGIN CERTIFICATE-----\n<........>'
使用jose 验证会得到false
const joseKey = await jose.importX509(cert, "RS256");
console.log(
await crypto.subtle.verify(
joseKey.algorithm.name,
joseKey,
byteArrays.signature,
byteArrays.body
)
)
// Note the following works
console.log(jose.jwtVerify(jwtRaw, joseKey))
使用jsrsaassign 也会得到false
var c = new jsrsasign.X509();
c.readCertPEM(cert);
var jsRsaAssignKey = await crypto.subtle.importKey(
"jwk",
jsrsasign.KEYUTIL.getJWKFromKey(c.getPublicKey()),
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
true,
["verify"]
); // Gets RSAKey first, then transforms into a JWK, then imported to get CryptoKey
console.log(
await crypto.subtle.verify(
jsRsaAssignKey.algorithm.name,
jsRsaAssignKey,
byteArrays.signature,
byteArrays.body
)
)
我哪里错了?
注意:请不要推荐 NodeJS 库。我需要运行脚本的环境不支持 Node 核心模块。
【问题讨论】:
-
我不是 JavaScript 开发人员。我不确定您要在这里做什么 encoder.encode(jwt.signature),。 JWT 签名采用 base-64 编码。因此,我认为您需要在调用 crypto.subtle.verify 之前对签名进行 base64 解码。
标签: google-cloud-platform jwt x509 webcrypto-api jose