I'm trying to encrypt a string using phpseclib AES in CBC mode (library's default):
$cipher = new Crypt_AES();
$cipher->setKey('abcdefghijklmnop');
$cipher->setIV(crypt_random_string($cipher->getBlockLength() >> 3));
$cipher->encrypt("hello world")
Then, I need to decrypt on nodejs using CryptoJS or similar.. I've tried different libs but no luck so far. I guess the issue is kind of related to the encoded output differ from each library.
Does anyone have a working example of how to implement this interoperability scenario?
Other library such as Crypto can be used.
An example Base64 output is MF9lCR4DaW1R0adIe03VEw==
So the idea is to decrypt as follows:
var helloWorld = CryptoJS.AES.decrypt("MF9lCR4DaW1R0adIe03VEw==", key).toString();
You need the previously generated IV during decryption. It doesn't have to be secret, but it has to be unpredictable (which it is in your case). You can send it along with the ciphertext. A common way is to prepend it to the ciphertext and slice it off during decryption.
CryptoJS supports two types of encryption. If you pass the key as a string, it will use OpenSSL's key derivation function to derive a new key with a salt. You don't want that, because you're using an explicit key. For that, you need to pass the key as WordArray (CryptoJS' native binary data structure). Additionally, the ciphertext is expected to be either an OpenSSL formatted string or a CipherParams object:
var message = CryptoJS.AES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse("MF9lCR4DaW1R0adIe03VEw==")
}, CryptoJS.enc.Utf8.parse('abcdefghijklmnop'), {
iv: iv // retrieve the IV somehow
}).toString(CryptoJS.enc.Utf8);