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

Node.js中使用Crypto加密解密PCM音频数据报错的解决方法

解决Node.js Crypto解密PCM数据时的「wrong final block length」错误

嘿,我看了你的代码和报错信息,问题主要出在两个地方,咱们一步步来解决:

1. 加密和解密用了不一样的密钥!

你加密的时候调用gen_key()生成密钥,解密时又重新调用了一次——这会生成完全不同的密钥啊!DES这类对称加密算法,解密必须和加密用同一个密钥,这是最核心的问题,直接导致解密失败。

2. 混合Buffer和字符串操作搞坏了二进制数据

Crypto模块处理二进制数据(比如PCM音频)时,全程用Buffer才是正确姿势。你代码里把cipher.update返回的Buffer直接和cipher.final('binary')返回的字符串拼接,Buffer转字符串时会默认用UTF-8编码,这会破坏二进制数据的完整性;解密时又直接把这个混乱的字符串传给decipher.update,自然会出现块长度不匹配的错误。

修正后的完整代码

const crypto = require('crypto');
const fs = require('fs');

// 确保你的gen_key生成符合DES要求的8字节密钥(DES密钥必须是8字节)
function gen_key() {
  // 示例:生成随机8字节密钥,你可以替换成自己的密钥生成逻辑
  return crypto.randomBytes(8);
}

function encrypt(buf, key) {
  const cipher = crypto.createCipheriv('des-ecb', key, Buffer.alloc(0));
  // 用Buffer.concat合并update和final的结果,全程不碰字符串
  return Buffer.concat([cipher.update(buf), cipher.final()]);
}

function decrypt(buf, key) {
  const decipher = crypto.createDecipheriv('des-ecb', key, Buffer.alloc(0));
  return Buffer.concat([decipher.update(buf), decipher.final()]);
}

// 只生成一次密钥,加密解密共用
const secretKey = gen_key();

// 读取PCM文件
const pcmBuffer = fs.readFileSync("test.pcm");
// 加密得到Buffer类型的密文
const encrypted = encrypt(pcmBuffer, secretKey);
// 解密得到原始PCM的Buffer
const decrypted = decrypt(encrypted, secretKey);

// 写入解密后的文件
fs.writeFileSync('dec.pcm', decrypted);

几个关键修改点

  • 固定密钥:只调用一次gen_key(),把密钥存起来给加密和解密用,保证两者密钥一致。
  • 全程用Buffer:加密和解密的所有操作都基于Buffer,用Buffer.concat()合并加密/解密过程中产生的Buffer片段,完全避免字符串转换带来的编码问题。
  • 去掉多余的编码参数:cipher.final()和decipher.final()默认返回Buffer,不需要指定'binary',减少不必要的编码转换风险。

另外要注意:DES算法的密钥长度必须是8字节(64位),如果你的gen_key()生成的密钥长度不对,也会出问题,一定要确保密钥符合这个要求哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:45:04