【问题标题】:How to decrypt an ArrayBuffer?如何解密 ArrayBuffer?
【发布时间】:2014-08-29 11:34:31
【问题描述】:

我一直在尝试使用 CryptoJS 解密 ArrayBuffer 对象,但到目前为止它总是返回一个空白 WordArray。文件(图像)在 iOS 和 Android 应用程序中加密,发送到服务器,然后下载到此 Web 应用程序中进行解密和显示。 iOS 和 Android 应用程序能够毫无问题地解密文件,因此加密过程没有任何问题。

文件使用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);

}

我的另一个问题是如何将WordArray 转换为ArrayBuffer

【问题讨论】:

    标签: javascript encryption cryptojs arraybuffer


    【解决方案1】:

    ArrayBuffer -> WordArray 的转换已在 CryptoJS 的issue 46 中讨论。因此,添加了 TypedWordArrayArrayBuffer,您也可以在其中传递 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` */
    

    要将生成的decryptedWordArray 重新转换为ArrayBuffer,最简单的方法可能是首先将其转换为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),请查看 Aletheiosthat 问题的回答(函数 wordToByteArray(wordArray) 然后执行 .buffer)。

    【讨论】:

    • 如果我将ArrayBuffer 直接提供给WordArray.createsigBytes 是NaN。如果我将它包装在Uint8Array 中,那将是一个很大的数字。 sigBytes 字段重要吗?无论哪种方式,AES.decrypt 返回一个空的 WordArray... 另外,当转换回 ArrayBuffer 时,Base64 字符串不会太大吗?正在解密的文件最大为 30MB...
    • sigBytes 仅在您使用 signature/MAC 时才重要,而在查看您的工作 String-encryption-example 时您不会这样做。如果您的文件那么大,那真的会出现问题,我会尝试找到更好的解决方案。你能不能提供一些测试数据(加密的ArrayBuffer(如果可能的话,一个小的)+key+IV),所以我可以自己尝试解密。谢谢。
    • 抱歉,sigBytes 完全错误。它们告诉WordArray 中保存了多少字节。不能是NaN。但实际上在本地测试时它们不适合我。 (当你包括lib-typedarrays.js
    • 我做了一个简单的 JSFiddle here,希望对您有所帮助......在那里创建的 ArrayBuffer 只是一个简单的文本文件(48 字节),我展示了将其解密为一个有效的 Base64 字符串,并且作为一个 ArrayBuffer,它不会...
    • 似乎CryptoJS 出于某种原因只解密 Base64-Strings。 (另见this 类似问题)可能最简单的解决方案是ArrayBuffer -> String -> decrypt() -> ArrayBuffer。我稍后会用该信息更新我的答案:)
    【解决方案2】:

    您可以使用web crypto API 直接解密arrayBuffer。 不用把二进制数据转成字符串,效率太低了,会导致内存和CPU的上升。

    【讨论】:

      猜你喜欢
      • 2020-08-02
      • 1970-01-01
      • 2012-08-11
      • 2017-05-10
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 2017-03-20
      • 2017-02-28
      相关资源
      最近更新 更多