简体   繁体   中英

Can't decrypt using CryptoJS (works in Java, Python)

I have a file that I encrypt using AES. Historically, I've had a set of tools (Java, Python) each of which is capable to both encrypt and decrypt these files. However, I've been having problems decrypting these files using CryptoJS.

The encrypted file has IV stored in the first 16 bytes, the rest is payload. During encryption key is formed by using hashing the password string via SHA-1 and using first 32 characters from the hex digest. I've gotten to the point where I can confirm that both IV and key used by CryptoJS is byte-wise identical to the ones used by other tools yet AES.decrypt() produces a buffer that I can't convert back to text.

Here's the decryption code. content and iv are binary strings read directly from file. password is a string with textual password. The code fails trying to convert the result to UTF8 (which I assume is due to the fact that decryption did not succeed).

function string2bytes(s) {
    var bytes = [];

    for (var i = 0; i < s.length; i++) {
        bytes.push(s.charCodeAt(i));
    }

    return bytes;
}


function decryptData(content, ivx, password) {
    // build a key out of text password
    var key = CryptoJS.SHA1(password).toString(CryptoJS.enc.Hex).substring(0, 32);
    console.log("key0: ", key);

    key = string2bytes(key)
    console.log(key);

    // Convert IV from binary string to WordArray
    var iv = CryptoJS.enc.Latin1.parse(ivx);
    console.log("IV: ", iv.toString(CryptoJS.enc.Hex));


    var decrypted = CryptoJS.AES.decrypt(content, key, { iv: iv });

    console.log("raw decrypted: ", decrypted);
    console.log("decrypted: ", iv.toString(CryptoJS.enc.Latin1));
    console.log("decrypted: ", iv.toString(CryptoJS.enc.Utf8));
}

Any help would be appreciated.

Found a solution by sticking to WordArrays (even for the arguments where a binary string is ostensibly OK): The following function does work. The arguments are as follows:

  • data is a base64 string with encrypted text
  • password is a regular string with password
  • iv is a base64 string with an IV.

so

 function decryptData(data, password, iv) {
    var data = CryptoJS.enc.Base64.parse(data);
    var key = CryptoJS.SHA1(password).toString(CryptoJS.enc.Hex).substring(0, 32);
    key = CryptoJS.enc.Base64.parse(btoa(key));

    var iv  = CryptoJS.enc.Base64.parse(iv);
    var decrypted = CryptoJS.AES.decrypt({ciphertext: data}, key, {iv: iv});
    return decrypted.toString(CryptoJS.enc.Utf8);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM