我已经能够在jwt.io的 Web UI 上验证 GCP ID 令牌,但我很难在 JS 中的代码中复制它。
我已经使用了 thejose
和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 核心模块。