I inherited a project years ago and and we started randomly having issues with phpseclib 2.x not decrypting anymore just a few days ago and I'm pulling my hair out on this one. No code changed in our projects but the decrypt function literally stopped working, encryption is fine, but even in a test environment decrypting does nothing, and the errors are none or basically so vague they are useless. So, we went to 3.0 but the original developer of this project didn't use an initialization vector as it wasn't required in version 2, it is required in version 3.
My question is how do we decrypt using AES with no IV in version 3? I can't find anywhere in the documentation how to do this and phpseclib throws an error if I don't provide an IV.
So basically, before:
$aes = new AES();
$aes->setKey('secret_key');
$enc_data = $aes->encrypt('abcdefg');
$dec_data = $aes->decrypt($enc_data);
New version:
$aes = new AES('cbc'); //or whatever cipher
$aes->setIV('something');
$aes->setKey('secret_key');
$enc_data = $aes->encrypt('abcdefg');
$dec_data = $aes->decrypt($enc_data);
Now in 3.0, AES requires a cypher to be declared which looks like CBC was the default in 2, but I cannot see what to do if no IV was added in 2.0 and it needs to be added in 3.0. I have tried but can't add '', passing no argument at all, null, etc., so it's like if someone didn't use an initialization vector using version 2, they can't decrypt using 3...? I looked through the 2.0 documentation and it defaults to and empty string from what I can tell, I can't pass that in 3.0.
Has anyone run into this? Anyone have a good idea on how to fix it? I completely removed 2.0 from this server and re-added it and I still can't decrypt with it, I'm guessing some update in apache or php broke something but I can't reproduce it on my other servers.
In V2, CBC and a zero IV are used by default, i.e. an IV with 16 0x00 values. In V3, mode and IV must be explicitly specified.
The following codes therefore result in the same ciphertext:
With V2:
$key = hex2bin("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
$plaintext = "The quick brown fox jumps over the lazy dog";
$aes = new AES();
$aes->setKey($key);
$enc_data = $aes->encrypt($plaintext);
$dec_data = $aes->decrypt($enc_data);
print(bin2hex($enc_data) . PHP_EOL); // bce46469e2f7ab6b7ea767bd3252529a843ba24e890e567ef600c4a6e1051ffc2012305e362438463838fad4043c22a6
print($dec_data . PHP_EOL); // The quick brown fox jumps over the lazy dog
With V3:
$key = hex2bin("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
$iv = hex2bin("00000000000000000000000000000000");
$plaintext = "The quick brown fox jumps over the lazy dog";
$aes = new AES('cbc');
$aes->setKey($key);
$aes->setIV($iv);
$enc_data = $aes->encrypt($plaintext);
$dec_data = $aes->decrypt($enc_data);
print(bin2hex($enc_data) . PHP_EOL); // bce46469e2f7ab6b7ea767bd3252529a843ba24e890e567ef600c4a6e1051ffc2012305e362438463838fad4043c22a6
print($dec_data . PHP_EOL); // The quick brown fox jumps over the lazy dog
Note that a static IV, like a zero IV, is insecure.