在Node.js中使用Jose 4.11为JWS签名令牌实现JWE加密
解决Jose Node.js中JWS转JWE链式加密的问题
原代码存在的关键问题
- 签名算法与密钥不匹配:用RSA密钥却指定
ES256算法,实际应匹配RS256 - JWE加密参数格式错误:
CompactEncrypt要求传入二进制数据(Buffer/Uint8Array),而非字符串形式的JWS - 加密密钥算法错误:
ES256是签名算法,加密需使用RSA类加密算法(如RSA-OAEP-256)
修正后的代码实现
1. 修复签名函数createJWS
import jose from 'jose' import NodeRSA from 'node-rsa' export const createJWS = async (userId) => { const payload = { 'urn:userId': userId } // 导入RSA私钥(对应RS256签名算法) const secretPkcs8Base64 = process.env.SMART_PRIVATE_KEY const key = new NodeRSA() key.importKey(Buffer.from(secretPkcs8Base64, 'base64'), 'pkcs8-private-der') const privateKey = key.exportKey('pkcs8') // 修正:用RS256算法导入密钥,与签名算法一致 const rsaPrivateKey = await jose.importPKCS8(privateKey, 'RS256') const assertion = await new jose.SignJWT(payload) .setProtectedHeader({ alg: 'RS256' }) // 算法与密钥匹配 .setIssuer('demolive') .setExpirationTime('5m') .sign(rsaPrivateKey) return assertion }
2. 修正加密函数encryptAsJWE
import jose from 'jose' export const encryptAsJWE = async (jws) => { // 导入用于加密的RSA公钥(使用RSA-OAEP-256加密算法) const idzPublicKey = process.env.IDZ_PUBLIC_KEY // 修正:用加密算法RSA-OAEP-256导入公钥 const rsaPublicKey = await jose.importSPKI(idzPublicKey, 'RSA-OAEP-256') // 修正:将JWS字符串转为Buffer传入CompactEncrypt const jwe = await new jose.CompactEncrypt(Buffer.from(jws)) .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' }) // 指定加密和内容加密算法 .encrypt(rsaPublicKey) return jwe }
3. 调用示例
const jws = await createJWS("myUserId"); const jwe = await encryptAsJWE(jws);
内容的提问来源于stack exchange,提问作者Benoit Patra
相关产品推荐
相关产品推荐

