You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:15:06