He estado tratando de descifrar un objeto ArrayBuffer usando CryptoJS, pero hasta ahora siempre devuelve un WordArray en blanco. Los archivos (imágenes) se cifran en una aplicación de iOS y Android, se envían a un servidor y se descargan en esta aplicación web para descifrarlos y mostrarlos. Las aplicaciones de iOS y Android pueden descifrar los archivos sin problemas, por lo que no hay nada de malo en el proceso de cifrado.

Los archivos se descargan con un XMLHttpRequest con responseType establecido en arraybuffer. Aquí está mi código hasta ahora:

// 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);

}

Otra pregunta que tengo es cómo convertir un WordArray en un ArrayBuffer.

10
jjv360 29 ago. 2014 a las 15:34

2 respuestas

La mejor respuesta

La conversión de ArrayBuffer -> WordArray se ha discutido en CryptoJS's número 46. Por esa razón, se agregó un TypedWordArray donde también puede pasar un ArrayBuffer.


Para usar eso, adicionalmente incluya el siguiente script:

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

Entonces puedes simplemente hacer:

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

/* perform decryption of `wordArray` */

Para reconvertir el decryptedWordArray resultante en un ArrayBuffer, el enfoque más simple probablemente sería convertirlo primero en un Base64-String (como se discutió here) y luego decodifique esa cadena al ArrayBuffer deseado (consulte aquí). Todo el procedimiento se vería así:

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

Editar:

Para una conversión más eficiente (no es necesario un intermedio Base64String), consulte la respuesta Aletheios a esa pregunta (la función wordToByteArray(wordArray) y luego .buffer).

11
Community 23 may. 2017 a las 12:16

Puede usar la web crypto API para descifrar directamente arrayBuffer. No es necesario convertir los datos binarios en una cadena, que es tan ineficiente y podría causar aumentos de memoria y CPU.

-2
邹俊辉 17 sep. 2019 a las 08:28