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

如何实现Uint8Array与字符串互转及解决eccrypto解密报错

解决eccrypto.js加密后JSON序列化/反序列化的解密错误及Uint8Array互转问题

Hey, I see exactly what's going wrong here—let's break this down and fix it step by step.

问题根源

When you use JSON.stringify() on the encrypted object returned by eccrypto, all the Uint8Array fields (iv, ephemPublicKey, ciphertext, mac) get converted into plain JavaScript arrays (like [12, 34, 56]). But eccrypto.decrypt() expects Buffer or Uint8Array types for these fields, not regular arrays. That's why you're hitting the "bad public key" error—your parsed ephemPublicKey is no longer a valid cryptographic key type.

解决方案:序列化前转十六进制,解析后转回Buffer

We need to convert each Uint8Array field to a hex string before serializing to JSON, then convert them back to Buffer (which is compatible with eccrypto) after parsing.

修改后的完整可运行代码

const eccrypto = require('eccrypto');

// B's public key (Buffer type)
const publicKeyB = Buffer.from("0418c7ced07c0c17f42b132747c70fddb6b31ea0ad349c2e9f800f48f0a73c2ea028d41b239077a48136ce546f9d2811bf1ec311c56e6a41f33906a1fc2472e451", 'hex');
// B's private key (Buffer type)
const privateKeyB = Buffer.from("9a2d66404b69023c2c45da81ca4b696a8234b7ae53ea6b7ffc0d6bdd0e0e3279", 'hex');

eccrypto.encrypt(publicKeyB, Buffer.from('Message to encrypt')).then(function(encrypted) {
  console.log('Original encrypted object:', encrypted);

  // Step 1: Convert Uint8Array fields to hex strings for JSON serialization
  const serializableEncrypted = {
    iv: encrypted.iv.toString('hex'),
    ephemPublicKey: encrypted.ephemPublicKey.toString('hex'),
    ciphertext: encrypted.ciphertext.toString('hex'),
    mac: encrypted.mac.toString('hex')
  };
  const encoded = JSON.stringify(serializableEncrypted);
  console.log('Serialized JSON:', encoded);

  // Step 2: Parse JSON and convert hex strings back to Buffer
  const parsed = JSON.parse(encoded);
  const actual = {
    iv: Buffer.from(parsed.iv, 'hex'),
    ephemPublicKey: Buffer.from(parsed.ephemPublicKey, 'hex'),
    ciphertext: Buffer.from(parsed.ciphertext, 'hex'),
    mac: Buffer.from(parsed.mac, 'hex')
  };
  console.log('Restored object after parsing:', actual);

  // Now decryption will work correctly
  eccrypto.decrypt(privateKeyB, actual).then(function(plaintext) {
    console.log("Decrypted message:", plaintext.toString());
  }).catch(err => {
    console.error('Decryption error:', err);
  });
}).catch(err => {
  console.error('Encryption error:', err);
});

Uint8Array与字符串的互转方法

For your question about converting Uint8Array to strings and back, hexadecimal strings are the best choice—they're compact, human-readable, and preserve all binary data perfectly:

1. Uint8Array → Hex String

// Node.js (using Buffer, which is a subclass of Uint8Array)
const buf = Buffer.from([0x12, 0x34, 0x56]);
const hexStr = buf.toString('hex'); // Output: "123456"

// Browser-only pure Uint8Array conversion
function uint8ArrayToHex(arr) {
  return Array.from(arr)
    .map(byte => byte.toString(16).padStart(2, '0')) // Ensure 2-digit hex
    .join('');
}

2. Hex String → Uint8Array/Buffer

// Node.js (convert to Buffer)
const buf = Buffer.from(hexStr, 'hex');

// Browser-only (convert to Uint8Array)
function hexToUint8Array(hexStr) {
  const arr = [];
  for (let i = 0; i < hexStr.length; i += 2) {
    arr.push(parseInt(hexStr.substr(i, 2), 16));
  }
  return new Uint8Array(arr);
}

Why Direct JSON.stringify Fails?

JSON doesn't natively support binary types like Uint8Array or Buffer. It automatically converts these objects to their underlying array representations. When you parse the JSON back, you get a plain array instead of the original binary type—this breaks eccrypto's validation checks for cryptographic keys and data.

内容的提问来源于stack exchange,提问作者Shubham Dhakal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:43:36