Node.js使用aes-256-ctr算法加解密图片文件失效问题求助
修复方案
你的代码问题出在解密逻辑的拼接错误,修复后可正常支持图片等所有二进制格式文件的加解密:
核心错误点
加密逻辑是将16位随机IV拼接在密文前输出,解密时你已经将IV从加密文件的前16位拆分出来,仅对后续的密文内容做解密,但最终返回结果时错误把IV再次拼接在了明文内容前面。
图片属于强校验的二进制格式,文件头多16位无关字节就会完全无法识别,而普通文本文件即使开头多了异常字符也能显示后续内容,所以你会误以为普通文件加解密正常。
修正后的完整代码
const crypto = require("crypto"); const fs = require("fs"); const algorithm = "aes-256-ctr"; let key = "SecretKey"; key = crypto.createHash("sha256").update(String(key)).digest("base64").substr(0, 32); const encrypt = (buffer) => { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv(algorithm, key, iv); const result = Buffer.concat([iv, cipher.update(buffer), cipher.final()]); return result; }; // 仅修改了decrypt函数的返回拼接逻辑 const decrypt = (encrypted) => { const iv = encrypted.slice(0, 16); encrypted = encrypted.slice(16); const decipher = crypto.createDecipheriv(algorithm, key, iv); // 移除了错误拼接的iv,仅返回解密后的明文内容 const result = Buffer.concat([decipher.update(encrypted), decipher.final()]); return result; }; // 加密示例:不覆盖原文件,输出加密文件到sun.jpg.enc // fs.readFile("./sun.jpg", (err, file) => { // if (err) return console.log(err.message); // const encryptedFile = encrypt(file); // fs.writeFile("./sun.jpg.enc", encryptedFile, (err) => { // if (err) return console.log(err.message); // console.log("File encrypted sucessfully"); // }); // }); // 解密示例:从加密文件sun.jpg.enc读取,输出解密后的文件到sun_dec.jpg fs.readFile("./sun.jpg.enc", (err, file) => { if (err) return console.error(err.message); const decryptedFile = decrypt(file); fs.writeFile("./sun_dec.jpg", decryptedFile, (err) => { if (err) return console.log(err.message); console.log("File decrypted sucessfully"); }); });
额外注意事项
- 不要直接覆盖原文件,加密解密都输出为新的独立文件,避免操作失误导致原文件永久丢失
- 不要对图片等二进制文件调用
toString()方法,输出的乱码没有参考价值,还可能干扰结果判断 - 生产环境不要硬编码密钥在代码中,建议通过环境变量、配置文件等方式安全传入
内容的提问来源于stack exchange,提问作者Dhakal Rupesh
相关产品推荐
相关产品推荐

