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
相关产品推荐
相关产品推荐

