Closed shujaat-github closed 2 years ago
I can't reproduce the error (with java version "17.0.1" and PHP 7.4.27). For example, the code below works fine, Java
AesEncryption aes = new AesEncryption("cbc", 256);
byte[] encryptedData = aes.encrypt("Hello", "PASSWORD");
System.out.println(new String(encryptedData));
//JnTRpJ2ql5ATHmiRWJsAO8Ek6DDLiAy/9HV0EncIPzFFfY4FnytwCQFvcb5z/lms1mp0VBP6w02SJLHW2BpycUZMD0vioTx96LzkEnmRZNU=
PHP
$aes = new AesEncryption("cbc", 256);
$ct = 'JnTRpJ2ql5ATHmiRWJsAO8Ek6DDLiAy/9HV0EncIPzFFfY4FnytwCQFvcb5z/lms1mp0VBP6w02SJLHW2BpycUZMD0vioTx96LzkEnmRZNU=';
$pwd = "PASSWORD";
var_dump($aes->decrypt($ct, $pwd));
//string(5) "Hello"
Could you give me you Java and PHP versions, and a more detailed example of code usage and output?
Tested using both PHP v7.4.25 and v7.4.3.
Java (Microsoft Build of OpenJDK): I use latest version of Visual Studio Code v1.71.2 and Extension Pack for Java Extension for Java development in VS Code.
java --version
openjdk 17.0.4.1 2022-08-12 LTS
OpenJDK Runtime Environment Microsoft-40354 (build 17.0.4.1+1-LTS)
OpenJDK 64-Bit Server VM Microsoft-40354 (build 17.0.4.1+1-LTS, mixed mode, sharing)
Anything I encrypt in Java I cannot decrypt in PHP as it fails with MAC check failed error, HOWEVER, anything I encrypt in PHP I can decrypt in Java.
Java:
AesEncryption aes = new AesEncryption("cbc", 256);
byte[] encryptedData = aes.encrypt("Hello", "PASSWORD");
System.out.println(new String(encryptedData));
//Rj65uM9cRkuGNdggFf4gUTUkF5G+HINn4Gp+4CBhRS481uMAvhvk4OmEUejkfDps0kcyvJLhGHj3QLp3uq794up9Uol/nsiXdApzOoxY0yc=
PHP
$aes = new AesEncryption("cbc", 256);
$ct = 'Rj65uM9cRkuGNdggFf4gUTUkF5G+HINn4Gp+4CBhRS481uMAvhvk4OmEUejkfDps0kcyvJLhGHj3QLp3uq794up9Uol/nsiXdApzOoxY0yc=';
$pwd = "PASSWORD";
var_dump($aes->decrypt($ct, $pwd));
//MAC check failed!NULL
Thanks for all the details. Unfortunately, I still can't reproduce the error. Your Java ciphertext decrypts fine with PHP in my environment. Can you do me a favor? Can you remove verification (comment out https://github.com/tasos-py/AES-Encryption-Classes/blob/master/AesEncryption.class.php#L109), to see what the plaintext looks like?
I get:
Padding is invalid!NULL
when I comment out the following line:
Any suggestions or ideas are welcomed. I would be happy to test this issue in any way you wish.
AES-Encryption-Classes is quite stable and helpful library. I have tested encryption decryption using C++ and PHP and it work flawlessly. However, in case of Java and PHP I face the issue mentioned above.
I don't get this issue on my PC, so I really appreciate you helping me in debugging. So, now we know the problem is somewhere in padding. Could you replace Cipher.unpad()
, https://github.com/tasos-py/AES-Encryption-Classes/blob/master/AesEncryption.class.php#L486 with the code bellow?
private function unpad($data) {
$pad = ord(mb_substr($data, -1, 1, "8bit"));
$count = substr_count(mb_substr($data, -$pad, $pad, "8bit"), chr($pad));
var_dump(bin2hex($data));
var_dump($pad);
var_dump($count);
if ($pad < 1 || $pad > 16 || $count != $pad) {
throw new RuntimeException("Padding is invalid!");
}
return mb_substr($data, 0, -$pad, "8bit");
}
This should show us the last block, pad and pad length. It should be
string(32) "48656c6c6f0b0b0b0b0b0b0b0b0b0b0b"
int(11)
int(11)
Here is the output:
string(32) "e74851067cc8f5195e6b27b802770ee9" int(233) int(1) Padding is invalid!NULL
Actually, the problem is not padding, because MAC check happens before decryption. It's either in key generation or data slicing. Please go to https://github.com/tasos-py/AES-Encryption-Classes/blob/master/AesEncryption.class.php#L108 and add those lines,
var_dump(bin2hex($salt));
var_dump(bin2hex($iv));
var_dump(bin2hex($ciphertext));
var_dump(bin2hex($mac));
var_dump(bin2hex($aesKey));
var_dump(bin2hex($macKey));
Snapshot for reference:
string(32) "31323334353637383930313233343536" string(32) "31323334353637383930313233343536" string(32) "3cd6e300be1be4e0e98451e8e47c3a6c" string(64) "d24732bc92e11878f740ba77baaefde2ea7d52897f9ec897740a733a8c58d327" string(64) "8704897df8d4a3b036c076e476807959e27b82cc32992638b64d1876168a209a" string(64) "84a79ca810cac775a3f094063edcacb181adab5dab73fd729bc7cb640961b6aa" string(32) "e74851067cc8f5195e6b27b802770ee9" int(233) int(1) Padding is invalid!NULL
Updated previous comment with required changes.
Thanks. I can't make sense of your salt and IV. Hex decoded, they're both "1234567890123456". According to your ciphertext, they should be "463eb9b8cf5c464b8635d82015fe2051" and "35241791be1c8367e06a7ee02061452e" (hex encoded). And I don't see how mb_substr()
in AesEncryption.decrypt()
could produce "1234567890123456". Do you have any idea where those values could be coming from?
I am ashamed to take up so much of your precious time even though the mistake was on my part. I had accidentally hardcoded the salt and iv.
@tasos-py Thank you very much for your valuable time. I am very grateful to you.
Programmers like me are forever in your debt for such a great library!
Glad to hear that! I'll be closing this issue now, since it's just a typo basically. And don't worry about it, those things happen all the time
I can encrypt and decrypt data in Java but if I encrypt data in Java then I can't decrypt it in PHP and I get MAC check failed error.
Java Code:
Now when I try to decrypt encryptedString in PHP using the same password, I get this error: