React Native中CryptoJS AES解密无法还原EPUB/ZIP文件问题求助
解决React Native中CryptoJS加密解密EPUB/ZIP文件后无法还原的问题
我看了你加密解密EPUB文件的代码,问题出在文件读写的编码处理逻辑上,导致数据被重复编码,最终解密后的文件和原文件不一致。咱们一步步拆解问题:
问题根源分析
- 加密阶段的错误:
你把AES.encrypt得到的密文(ciphertext.toString()本身已经是Base64格式的字符串),再用base64编码写入文件。这相当于把Base64字符串又做了一次Base64编码,直接导致文件体积膨胀(原文件2.49MB,加密后变成3.11MB就是这个原因)。 - 解密阶段的错误:
读取加密文件时用base64编码,拿到的是经过两次Base64编码的数据,解密后又转成Base64再写入,整个流程的编码逻辑完全混乱,自然无法还原原文件。
修正后的加密代码
encrypt() { // ENCRYPTION RNFetchBlob.fs.readFile(`${RNFetchBlob.fs.dirs.DownloadDir}/startup.epub`, 'base64') .then(result => { console.log('startup.epub read data: ', result); // 将Base64字符串转为CryptoJS可处理的WordArray const plaintextWordArray = CryptoJS.enc.Base64.parse(result); // 加密 const ciphertext = CryptoJS.AES.encrypt(plaintextWordArray, key); // 密文toString()默认是Base64格式,直接用utf8编码写入文件(不要再次Base64编码) return RNFetchBlob.fs.writeFile( `${RNFetchBlob.fs.dirs.DownloadDir}/startup_enc.dat`, ciphertext.toString(), 'utf8' ); }) .then(() => { console.log('startup_enc.dat file written'); this.decrypt(); }) .catch(error => { console.log('Encryption error: ', error); }); }
修正后的解密代码
decrypt() { // DECRYPTION RNFetchBlob.fs.readFile(`${RNFetchBlob.fs.dirs.DownloadDir}/startup_enc.dat`, 'utf8') .then(result => { console.log('startup_enc.dat data: ', result); // 解密得到WordArray const decryptedWordArray = CryptoJS.AES.decrypt(result, key); // 将WordArray转成Base64字符串,再用base64编码写入文件还原原二进制 const plaintextBase64 = decryptedWordArray.toString(CryptoJS.enc.Base64); return RNFetchBlob.fs.writeFile( `${RNFetchBlob.fs.dirs.DownloadDir}/startup_dec.epub`, plaintextBase64, 'base64' ); }) .then(() => { console.log('startup_dec.epub file written'); }) .catch(error => { console.log('Decryption error: ', error); }); }
关键调整点说明
- 加密时:密文本身是Base64字符串,写入文件用
utf8编码,避免重复Base64编码。 - 解密时:读取加密文件用
utf8拿到原始密文字符串,解密后转成Base64,再用base64编码写入,还原原文件的二进制数据。 - 用
CryptoJS.enc.Base64.parse()和toString(CryptoJS.enc.Base64)来处理WordArray和Base64的转换,确保数据格式正确。
这样处理后,解密后的文件大小应该和原文件一致,也能正常打开了。
内容的提问来源于stack exchange,提问作者Sagaryal
相关产品推荐
相关产品推荐

