在wordArray到ByteArray的转换中超过CryptoJS最大调用堆栈大小



我正在尝试使用CryptoJS在react客户端应用程序中实现加密和解密。加密和解密可以在没有错误的情况下完成,但它只适用于小文件大小的情况。在视频文件(9MB(的解密过程中,将wordArray转换为ByteArray时出现错误,称超过了最大调用堆栈大小。处理此转换的代码来自:GitHub

错误:超过的最大调用堆栈大小

代码:

wordArrayToByteArray = (wordArray,length) => {
if(wordArray.hasOwnProperty("sigBytes") && wordArray.hasOwnProperty("words")){
length = wordArray.sigBytes;
wordArray = wordArray.words;
}
let result = [];
let bytes;
let i = 0;
while(length > 0){
bytes = this.wordToByteArray(wordArray[i],Math.min(4,length));
length -= bytes.length;
result.push(bytes);
i++;
}
return [].concat.apply([],result);
}
wordToByteArray = (word, length) => {
var ba = [],
i,
xFF = 0xFF;
if (length > 0)
ba.push(word >>> 24);
if (length > 1)
ba.push((word >>> 16) & xFF);
if (length > 2)
ba.push((word >>> 8) & xFF);
if (length > 3)
ba.push(word & xFF);
return ba;
}
decryptFile = (downloaded) =>{ 
//convert unit array(encrypted file) to string
let encryptedString = this.uintToString(downloaded);
//decrypt and get wordArray
const decrypted = cryptojs.AES.decrypt(encryptedString,"123");
console.log(decrypted);
//convert wordArray to string
let decryptedString = decrypted.toString(cryptojs.enc.Utf8);

// form a new word array
const wordArray = cryptojs.enc.Hex.parse(decryptedString);

//convert new wordArray to byteArray
return this.wordArrayToByteArray(wordArray,Object.keys(wordArray).length);
}
uintToString = (uintArray) => {
const decodedStr = new TextDecoder("utf-8").decode(uintArray);
return decodedStr;
}
onDownload = () => {
ipfs.get(this.state.ipfsHash,(error,files)=>{
files.forEach((file)=>{
console.log(file.path);
const decryptedFile = this.decryptFile(file.content);
const arrayBufferView = new Uint8Array(decryptedFile);
const blob = new Blob([arrayBufferView],{type: "video/mp4"});
console.log(blob);
fileSaver.saveAs(blob,"curseTheInternet.mp4");
})
})
}

或者对客户端的加密库有其他建议吗?

问题来自于您对[].concat.apply([], result)的使用,如果结果太大,这将导致您看到的错误。据我所知,你正在用这个来压平单词数组。要避免此错误,请尝试使用.flat.

使用此改进版

static wordArrayToByteArray(wordArray: CryptoJS.lib.WordArray, length: number): Uint8Array {
let words: any = wordArray;
if (wordArray.hasOwnProperty("sigBytes") && wordArray.hasOwnProperty("words")) {
length = wordArray.sigBytes;
words = wordArray.words;
}
let result: number[] = [];
let bytesAdded;
let i = 0;
while (length > 0) {
bytesAdded = this.wordToByteArray(result, words[i], Math.min(4, length));
length -= bytesAdded.length;
i++;
}
return new Uint8Array(result);
}
private static wordToByteArray(result, word, length): number {
const lengthBefore = result.length;
const xff = 0xFF;
if (length > 0)
result.push(word >>> 24);
if (length > 1)
result.push((word >>> 16) & xff);
if (length > 2)
result.push((word >>> 8) & xff);
if (length > 3)
result.push(word & xff);
return result.length - lengthBefore;
}

最新更新