node-jose西里尔字符兼容问题:西里尔文加密后解密失败如何解决?
问题根因
- 核心原因是加密时直接传入
JSON.stringify()返回的字符串,node-jose的update方法默认不会自动将包含多字节字符(西里尔、中文等)的字符串转为UTF-8编码的二进制数据,导致加密前的原始数据编码异常 - 解密时直接调用
decrypted.payload.toString()默认用ASCII编码转换多字节内容,也会出现乱码
可行解决方案
仅需对加解密阶段的编解码逻辑做两处修改,即可兼容所有非拉丁字符的加解密场景,修改后的完整代码如下:
let keystore1; let keystore2; keystore1 = JWK.createKeyStore(); keystore2 = JWK.createKeyStore(); const input = { message: { text: 'Привет!' } }; const priv1 = await keystore1.generate('EC', 'P-256', { kid: '1gBdaS-G8RLax2qgObTD94w', key_ops:["sign", "decrypt", "unwrap"] }); const priv2 = await keystore2.generate('EC', 'P-256', { kid: '2gBdaS-G8RLax2qgObTD94v', key_ops:["sign", "decrypt", "unwrap"] }); const pub1 = await JWK.asKey(priv1.toJSON()); const pub2 = await JWK.asKey(priv2.toJSON()); const encrypted = await JWE.createEncrypt( { format: 'compact', fields: { alg: 'ECDH-ES', enc: 'A128CBC-HS256', cty: 'json', }, }, { key: pub2, } ) // 加密时显式将字符串转为UTF-8编码的Buffer .update(Buffer.from(JSON.stringify(input), 'utf8')) .final(); console.log('encrypted', encrypted); const decrypted = await JWE.createDecrypt(priv2).decrypt(encrypted); // 解密时显式指定UTF-8编码解析payload console.log('decrypted', JSON.parse(decrypted.payload.toString('utf8')));
以上修改不会影响原有拉丁字符的加解密逻辑,同时对中文、日文、阿拉伯文等所有非拉丁字符都兼容。
内容的提问来源于stack exchange,提问作者ImPuLsE
相关产品推荐
相关产品推荐

