My first time using CryptoJS, and I'm struggling to decrypt a string I encrypted using openssl_encrypt() in PHP.
PHP 5.6.13.0 and CryptoJS 3.1.2
First, my PHP:
$encryptHash = hash_pbkdf2("sha256", "0000", "secret", 1000, 32);
var_dump($encryptHash);
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
var_dump(bin2hex($iv));
$encrypted = openssl_encrypt("hello! this is my string!", 'aes-256-cbc', $encryptHash, 0, $iv);
var_dump($encrypted);
$encrypted = base64_encode($encrypted.":".bin2hex($iv));
echo "\r\n".$encrypted;
This gives me the following output:
string(32) "59b6ab46d379b89d794c87b74a511fbd"
string(32) "0aaff094b6dc29742cc98a4bac8bc8f9"
string(44) "xHIxg1HDUOqyhBmAaU2Sx3ct8GaKaeE5w4d1KM1yuDw="
eEhJeGcxSERVT3F5aEJtQWFVMlN4M2N0OEdhS2FlRTV3NGQxS00xeXVEdz06MGFhZmYwOTRiNmRjMjk3NDJjYzk4YTRiYWM4YmM4Zjk=
Now my JS:
var encryptedString = "eEhJeGcxSERVT3F5aEJtQWFVMlN4M2N0OEdhS2FlRTV3NGQxS00xeXVEdz06MGFhZmYwOTRiNmRjMjk3NDJjYzk4YTRiYWM4YmM4Zjk=";
var key256Bits = CryptoJS.PBKDF2("0000", "secret", { keySize: 128/32, iterations: 1000, hasher: CryptoJS.algo.SHA256 });
var keyAsHex = key256Bits.toString(CryptoJS.enc.Hex);
/* keyAsHex = "59b6ab46d379b89d794c87b74a511fbd" */
var rawData = atob(encryptedString);
var rawPieces = rawData.split(":");
var crypttext = rawPieces[0];
var iv = rawPieces[1];
/* crypttext = "xHIxg1HDUOqyhBmAaU2Sx3ct8GaKaeE5w4d1KM1yuDw=" */
/* iv = "0aaff094b6dc29742cc98a4bac8bc8f9" */
/* So far so good? */
var plaintextArray = CryptoJS.AES.decrypt(
{ ciphertext: CryptoJS.enc.Base64.parse(crypttext) },
CryptoJS.enc.Hex.parse(keyAsHex),
{ iv: CryptoJS.enc.Hex.parse(iv) }
);
/* plaintextArray: d.WordArray.n.extend.init
sigBytes: -67
words: Array[8]
0: 1419734786
1: -2048883413
2: -1709437124
3: 736946566
4: 718053567
5: -64039355
6: 1868905697
7: -910423965 */
var output = CryptoJS.enc.Utf8.stringify(plaintextArray);
/* output = "" */
As you can see, my output is an empty string. Anyone attempted to do something similar? I'm stumped!
Edit
Turns out my key lengths were incorrect! Here's my working PHP (encrypt) and JS (decrypt) code:
PHP:
$encryptHash = hash_pbkdf2("sha256", "0000", "secret", 1000, 32, true);
var_dump($encryptHash);
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("aes-256-cbc"));
var_dump($iv);
$encrypted = openssl_encrypt("hello! this is a test!", "aes-256-cbc", $encryptHash, 0, $iv);
var_dump($encrypted);
$encrypted = base64_encode($encrypted.":".bin2hex($iv));
echo "\r\n".$encrypted;
Gives me the following:
string(32) "Y½FËy©ØyLçÀJQ▼¢▄▄êI╩öo§(NtÙת‼ç"
string(16) "àX§ $VÇ‼♣┘█²áÓßt"
string(44) "VIzzao8Wdo8HPM015v6c5Q77ervGUIVbL6ERKRXb0fU="
Vkl6emFvOFdkbzhIUE0wMTV2NmM1UTc3ZXJ2R1VJVmJMNkVSS1JYYjBmVT06ODU1ODE1MjAyNDU2ODAxMzA1ZDlkYmZkYTBlMGUxNzQ=
JS:
var encryptedString = "Vkl6emFvOFdkbzhIUE0wMTV2NmM1UTc3ZXJ2R1VJVmJMNkVSS1JYYjBmVT06ODU1ODE1MjAyNDU2ODAxMzA1ZDlkYmZkYTBlMGUxNzQ=";
var key256Bits = CryptoJS.PBKDF2("0000", "secret", { keySize: 256/32, iterations: 1000, hasher: CryptoJS.algo.SHA256 });
var rawData = atob(encryptedString);
var rawPieces = rawData.split(":");
var crypttext = rawPieces[0];
var iv = CryptoJS.enc.Hex.parse(rawPieces[1]);
var cipherParams = CryptoJS.lib.CipherParams.create({ciphertext: CryptoJS.enc.Base64.parse(crypttext)});
var plaintextArray = CryptoJS.AES.decrypt(
cipherParams,
key256Bits,
{ iv: iv }
);
var output = CryptoJS.enc.Utf8.stringify(plaintextArray);
/* output === 'hello! this is a test!' */