I have seen other questions which ask about creating the initialization vector (IV) for encryption and it seems using a random value is one option. However, I need to generate the IV for decryption, so I have to use the same one that the data was encrypted with based on some salt.
The node.js crypto function createDecipher says:
The implementation of crypto.createDecipher() derives keys using the OpenSSL function EVP_BytesToKey with the digest algorithm set to MD5, one iteration, and no salt.
For backwards compatibility with assets encrypted by other software, I need a different number of iterations, and a salt that I specify.
Continuing to read the documentation, it further says:
In line with OpenSSL's recommendation to use PBKDF2 instead of EVP_BytesToKey it is recommended that developers derive a key and IV on their own using crypto.pbkdf2() and to use crypto.createDecipheriv() to create the Decipher object.
Ok, that sounds good. The data I need to decrypt was encrypted using EVP_BytesToKey to get the key and IV, so I need to be compatible with that, though.
Anyway, the crypto.pbkdf2 function appears to take all the parameters I need it to, but the problem is, it does not appear to create an initialization vector.
The corresponding C code which did the decryption which this needs to be compatible with looks like this:
// parameters to function:
// unsigned char *decrypt_salt
// int nrounds
// unsigned char *decrypt_key_data <- the password
// int decrypt_key_data_len <- password length
// the following is not initialized before the call to EVP_BytesToKey
unsigned char decrypt_key[32], decrypt_iv[32];
EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), decrypt_salt, decrypt_key_data,
decrypt_key_data_len, nrounds, decrypt_key, decrypt_iv);
My attempt to use crypto.pbkdf2
to replicate this behavior:
crypto.pbkdf2(password, salt, nrounds, 32, "md5", (err, derivedKey) => {
if (err) throw err
console.log(derivedKey.toString("hex"))
})
The derivedKey
also does not match the key produced by the C code above. I'm not sure if that's even expected! I also tried key lengths of 48 and 64 but those didn't generate anything similar to the expected key and IV either.
Given the correct password, salt, and hashing rounds, how do I generate the same key and IV to decrypt with?