3
votes

My problem is that the newer versions of OpenSSL aren't compatible with default settings of CryptoJS.

The default hash used by openssl enc for password-based key derivation changed in 1.1.0 to SHA256 versus MD5 in lower versions. https://unix.stackexchange.com/questions/344150/why-can-one-box-decrypt-a-file-with-openssl-but-another-one-cant/344586#344586

By default, CryptoJS uses MD5 for its key derivation. OpenSSL used MD5, but now in OpenSSL versions >=1.1.0 it's using SHA256.

So if I pass -md md5 to OpenSSL, CryptoJS is compatible:

echo "Hello World" | openssl enc -aes-256-cbc -md md5 -pass pass:"Secret Passphrase" -e -base64

output: U2FsdGVkX19aufvaqQQ89scaApBos6oFCyqPj7IKUFk=

CryptoJS:

CryptoJS.AES.decrypt('U2FsdGVkX19aufvaqQQ89scaApBos6oFCyqPj7IKUFk=', 'Secret Passphrase').toString(CryptoJS.enc.Utf8);

output: "Hello World"


But now if I want to use SHA256 instead of MD5 (removing the -md md5):

echo "Hello World" | openssl enc -aes-256-cbc -pass pass:"Secret Passphrase" -e -base64

output: U2FsdGVkX1/5LLkFkTpawh1im4a/fCco5hS42cjn/fg=

CryptoJS:

CryptoJS.AES.decrypt('U2FsdGVkX1/5LLkFkTpawh1im4a/fCco5hS42cjn/fg=', 'Secret Passphrase').toString(CryptoJS.enc.Utf8);

output: null

How do I tell CryptoJS to use SHA256 instead of MD5 for its key derivation?

1

1 Answers

3
votes

It seems that CryptoJS "as-is" does not provide this flexibility. This is because the use of MD5 is hard coded into the function used to derive the key from the passphrase. You can see it happening here in OpenSSLKdf:

var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);

KDF stands for Key Derivation Function, and no digest is provided when it is created. That EvpKDF.create() in itself does have the possibility for different types of digests, as you can see in its configuration options:

        cfg: Base.extend({
            keySize: 128/32,
            hasher: MD5,
            iterations: 1
        }),

It also shows that MD5 is the default.

All of this implies that the decryption will work if you modify that first line to the following:

var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: C_algo.SHA256 }).compute(password, salt);

and indeed, after editing (as a test) that file cipher-core.js in your locally installed module, your last line of code does result in the desired Hello World.

The only way I see to reproduce this without modifying the CryptoJS module itself is by duplicating a whole chunk of code from the module into your own code.