Node.js crypto模块文件加解密decipher异常问题求助
Node.js crypto 文件加解密异常问题解决
问题分析
- 编码处理不匹配:加密时将文件流的Buffer直接以
utf8编码传入加密函数,但解密时直接将加密文件的Buffer按hex解析,逻辑矛盾。加密后的文件是hex格式文本,读取时需先转为utf8字符串再处理。 - 填充设置错误:
crypto.createCipheriv默认开启PKCS#7自动填充,你在解密时手动调用decipher.setAutoPadding(false),导致解密后残留填充字节,出现乱码。 - 流处理逻辑缺陷:手动监听
data和end事件易出现编码拼接问题,使用Node.js流管道(pipe)能更安全地处理数据流转。
修正后的代码
确保algorithm、key、iv定义符合算法要求(例如aes-256-cbc对应32字节key和16字节iv):
const fs = require('fs'); const crypto = require('crypto'); const algorithm = 'aes-256-cbc'; // 替换为你的32字节key和16字节iv,可通过Buffer.from确保字节长度正确 const key = Buffer.from('your-32-byte-secret-key-example', 'utf8'); const iv = Buffer.from('your-16-byte-iv-example', 'utf8'); const encryptFile = (inputPath, outputPath) => { const input = fs.createReadStream(inputPath); const output = fs.createWriteStream(outputPath); const cipher = crypto.createCipheriv(algorithm, key, iv); cipher.setEncoding('hex'); // 直接将加密结果转为hex字符串 // 用管道自动处理流数据,避免手动拼接错误 input.pipe(cipher).pipe(output); }; const decryptFile = (inputPath, outputPath) => { const input = fs.createReadStream(inputPath, 'utf8'); // 以utf8读取hex格式的加密文件 const output = fs.createWriteStream(outputPath); const decipher = crypto.createDecipheriv(algorithm, key, iv); input.on('data', (hexStr) => { const decryptedData = decipher.update(hexStr, 'hex', 'utf8'); output.write(decryptedData); }); input.on('end', () => { const finalDecrypted = decipher.final('utf8'); output.write(finalDecrypted); output.end(); }); }; // 调用示例(分别运行,注释另一个) // encryptFile('test.txt', 'test_encrypted.txt'); // decryptFile('test_encrypted.txt', 'test_decrypted.txt');
额外说明
- 若处理二进制文件(如图片、压缩包),不要使用
utf8编码,直接处理Buffer即可:加密时移除cipher.setEncoding('hex'),将加密后的二进制数据写入文件;解密时读取二进制文件,直接传入decipher.update(无需指定hex编码)。 - 生产环境禁止使用固定iv,应每次加密生成随机iv,并将iv与加密数据一同存储(iv无需保密,仅用于初始化加密算法)。
内容的提问来源于stack exchange,提问作者Fatih EGE
相关产品推荐
相关产品推荐

