2014-08-29 630 views
4

我一直試圖使用CryptoJS解密一個ArrayBuffer對象,但到目前爲止它總是返回一個空白的WordArray。文件(圖像)在iOS和Android應用程序中加密,發送到服務器,然後下載到此Web應用程序中進行解密和顯示。 iOS和Android應用程序能夠解密文件而沒有問題,因此加密過程沒有任何問題。如何解密ArrayBuffer?

這些文件與XMLHttpRequest一起下載,responseType設置爲arraybuffer。這裏是我到目前爲止的代碼:

// Decrypt a Base64 encrypted string (this works perfectly) 
String.prototype.aesDecrypt = function(key) { 

    var nkey = CryptoJS.enc.Hex.parse(key.sha256()); 
    return CryptoJS.AES.decrypt(this.toString(), nkey, { 
     iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'), 
     mode: CryptoJS.mode.CBC, 
     padding: CryptoJS.pad.Pkcs7 
    }).toString(CryptoJS.enc.Utf8); 

} 

// Decrypt a plain encrypted ArrayBuffer (this is the problem, it always outputs an empty WordArray) 
ArrayBuffer.prototype.aesDecrypt = function(key) { 

    // Get key 
    if (!key) return null; 
    var nkey = CryptoJS.enc.Hex.parse(key.sha256()); 

    // Get input (if I pass the ArrayBuffer directly to the create function, it returns 
    // a WordList with sigBytes set to NaN) 
    //var input = CryptoJS.lib.WordArray.create(this); 
    var input = CryptoJS.lib.WordArray.create(new Uint8Array(this)); 

    // Decrypt 
    var output = CryptoJS.AES.decrypt(input, nkey, { 
     iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'), 
     mode: CryptoJS.mode.CBC, 
     padding: CryptoJS.pad.Pkcs7 
    }); 

    // Output is an empty WordList 
    console.log("Output: ", output); 

} 

另一個問題我已經是你如何轉換WordArrayArrayBuffer

回答

5

ArrayBuffer -> WordArray的轉換已在中討論過CryptoJS的issue 46。出於這個原因,TypedWordArray,你也可以通過ArrayBuffer已被添加。


要使用另外包括以下腳本:

<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/lib-typedarrays.js"></script> 

然後,你可以簡單地做:

var wordArray = CryptoJS.lib.WordArray.create(arrayBuffer); 

/* perform decryption of `wordArray` */ 

重新轉換所產生的decryptedWordArrayArrayBuffer,最簡單的的方法可能會首先將其轉換爲Base64-String(如討論here),然後將該字符串解碼爲所需的ArrayBuffer(請參閱here)。整個過程會是這個樣子:

dcWordArray = ... // your decrypted WordArray 
dcBase64String = dcWordArray.toString(CryptoJS.enc.Base64); // to Base64-String 
dcArrayBuffer = base64DecToArr(dcBase64String).buffer; // to ArrayBuffer 

編輯:

爲了更有效地轉換(無中間Base64String必要)檢查Aletheios答案that問題(功能wordToByteArray(wordArray)然後做.buffer)。

+0

如果我將'ArrayBuffer'直接提供給'WordArray.create','sigBytes'是NaN。如果我用'Uint8Array'包裝它,這是相當多的。 sigBytes字段重要嗎?無論哪種方式,'AES.decrypt'返回一個空的WordArray ...此外,當轉換回'ArrayBuffer'不會Base64字符串太大?這些文件可以高達30MB,正在被解密...... – jjv360 2014-09-02 08:23:44

+0

'sigBytes'只有在使用'signature/MAC'時才重要,它會查看您正在工作的* String加密示例*。如果你的文件很大,那確實會遇到問題,我會盡力找到更好的解決方案。你可能會提供一些測試數據(加密的'ArrayBuffer'(如果可能的話)''key' +'IV'),所以我可以自己嘗試解密。謝謝。 – 2014-09-02 08:36:06

+1

對不起,'sigBytes'完全錯誤。他們告訴「WordArray」中保存了多少字節。一定不能是'NaN'。但實際上它們在本地測試時不適合我。 (當你包含'lib-typedarrays.js') – 2014-09-02 09:47:36