如何生成可匹配Keycloak访问令牌的x5t#S256头值?
问题原因
- 哈希对象错误:
x5t#S256是对完整的DER编码的X.509证书做SHA256哈希,不是对证书内的公钥做哈希,你当前代码取cert.publicKey计算指纹,计算对象本身就不符合标准要求。 - 编码格式错误:
x5t#S256要求哈希结果输出为无填充的URL安全Base64编码,你当前用的是十六进制编码,格式不匹配。
修正后的代码(基于forge库)
const fs = require('fs'); const forge = require('node-forge'); const pki = forge.pki; const certPem = fs.readFileSync('./src/mycert.pem', 'utf8'); const cert = pki.certificateFromPem(certPem); // 把证书转换为DER格式二进制 const certDer = pki.certificateToAsn1(cert); const certDerBytes = forge.asn1.toDer(certDer).getBytes(); // 计算SHA256哈希 const sha256 = forge.md.sha256.create(); sha256.update(certDerBytes); const hashBytes = sha256.digest().getBytes(); // 转换为无填充的URL安全Base64 const x5tS256 = forge.util.encode64(hashBytes) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); console.log(x5tS256); // 输出和Keycloak一致的szfuvFcylKT5PRso0QIWK5fE6mB3Pn08ya2crsp5h1U
更简便的实现方案
推荐用jose库,这是通用的JWT/JWK标准实现库,不需要手动处理编码转换逻辑:
const fs = require('fs'); const { calculateX5tS256 } = require('jose'); const certPem = fs.readFileSync('./src/mycert.pem', 'utf8'); const x5tS256 = await calculateX5tS256(certPem); console.log(x5tS256);
内容的提问来源于stack exchange,提问作者Ranieri Mazili
相关产品推荐
相关产品推荐

