CryptoJS可正确解密文本文件但图片解密后损坏问题求助
图片加密解密损坏问题修复方案
问题核心原因
- 解密时只读取了服务器返回的第一个数据块,忽略后续内容,导致加密数据不完整
- 用字符串中转二进制数据(
String.fromCharCode+Latin1编码),破坏了图片原始二进制字节,部分字节无法正确映射 - 加密后的数据存储/读取格式未统一,导致解密时解析错误
修复后的代码
加密代码(优化存储格式)
function uploadFile() { var file = fileupload.files[0]; var reader = new FileReader(); var key = document.getElementById("enc_key").value; reader.onload = function() { // 将文件二进制转成CryptoJS可处理的WordArray var wordArray = CryptoJS.lib.WordArray.create(reader.result); // 加密后明确转成Base64字符串(CryptoJS默认toString输出Base64) var encrypted = CryptoJS.AES.encrypt(wordArray, key).toString(); // 生成文本类型Blob存储加密内容,确保格式统一 var fileEnc = new Blob([encrypted], { type: 'text/plain' }); encryptAndUpload(fileEnc); // 下载文件加后缀,方便识别 downloadStringAsFile("encr.txt", encrypted); }; reader.readAsArrayBuffer(file); }
解密代码(核心修复)
async function decryptAndDownload_Unzipped(index) { // 省略获取file_url的逻辑... https.get(file_url, function(res) { var data = [], dataLen = 0; res.on('data', function(chunk) { data.push(chunk); dataLen += chunk.length; }).on('end', function() { // 合并所有数据块,得到完整的加密内容Buffer var buf = Buffer.alloc(dataLen); for (var i = 0, pos = 0; i < data.length; i++) { data[i].copy(buf, pos); pos += data[i].length; } // 将Buffer转成utf8字符串(加密时存的是Base64文本) var dec_file = buf.toString('utf8'); // 解密得到WordArray,转成Uint8Array保留原始二进制 var decryptedWordArray = CryptoJS.AES.decrypt(dec_file, key); var decryptedBytes = new Uint8Array(decryptedWordArray.sigBytes); for (var i = 0; i < decryptedWordArray.sigBytes; i++) { decryptedBytes[i] = (decryptedWordArray.words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; } // 用二进制数组生成Blob并下载 var saveByteArray = (function () { var a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; return function (bytes, name) { var blob = new Blob([bytes], { type: "application/octet-stream" }); var url = window.URL.createObjectURL(blob); a.href = url; a.download = name; a.click(); window.URL.revokeObjectURL(url); }; }()); saveByteArray(decryptedBytes, 'example.png'); }); }); }
修复关键点说明
- 完整读取加密数据:合并所有服务器返回的数据块,避免只取部分内容导致解密失败
- 二进制安全转换:解密后直接将WordArray转成Uint8Array二进制数组,跳过字符串中转,确保每个字节都正确保留
- 统一数据格式:加密时存储Base64格式的文本Blob,解密时按utf8读取,保证前后格式匹配
内容的提问来源于stack exchange,提问作者Ahmed Deghady
相关产品推荐
相关产品推荐

