0
<?php
$data = '1234';
$key = "QTqKQmuKF3DCqLDvGauM";
$iv = substr(hash('sha256', $key), 0, openssl_cipher_iv_length('AES-256-CBC'));
// prints encrypted
echo bin2hex(openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv)) . "n";
// prints decrypted
echo openssl_decrypt(hex2bin('f55a7fda24e12ab74d84ca09bed37f80'), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);

output:

f55a7fda24e12ab74d84ca09bed37f80
1234

These 5 lines. That's it. I've been trying to replicate these five lines in java and i just can't get the same output. Any help is appreciated. (The given php code runs, try it out if you want more cases).

My current Java Code :

public String decryptUsingKey(String strToDecrypt, String secret, String iv) {
        try {
            String salt = "test123";
            IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());
​
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
            KeySpec spec = new PBEKeySpec(secret.toCharArray(), salt.getBytes(), 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
​
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
            return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
        } catch (Exception e) {
            logger.error("Error while decrypting: " + e.toString());
        }
        return null;
    }
Anil Kumar
  • 127
  • 8
  • Post your current Java-code. – Topaco Nov 06 '19 at 07:36
  • @Topaco Added the snippet. – Anil Kumar Nov 06 '19 at 08:06
  • @Topaco The biggest mystery to me is how is openssl in PHP working when the key is just 20 bytes. It must be using some sort of padding? How do i figure out what padding? – Anil Kumar Nov 06 '19 at 08:07
  • 1
    Anyway - I see the following differences: (1) PHP implicitly pads with `0`-values, i.e. it actually uses the key `$key = "QTqKQmuKF3DCqLDvGauM\0\0\0\0\0\0\0\0\0\0\0\0"`, which must also be used in Java. (2) The Java-code uses PBKDF2, the PHP-code doesn't. (3) The hash is generated as a hexadecimal _string_ and the first 16 _characters_ of it are used for the IV. Here you have to pay attention to upper/lower-case in the Java/PHP-code. (4) in PHP the ciphertext is decoded from a hexadecimal string during decryption, in Java from Base64. – Topaco Nov 06 '19 at 11:20
  • @Topaco If i could figure out the 32 bit key used by openssl, my entire problem would be solved at this point. I tried the key you mentioned already, after reading [openssl php source](http://github.com/php/php-src/blob/master/ext/openssl/openssl.c#L6319). But the encrypted string is different when using with zero appended than without. – Anil Kumar Nov 06 '19 at 11:58
  • @Topaco Is there any other sort of padding you think might work? – Anil Kumar Nov 06 '19 at 12:00
  • @Topaco I just copied your line with backslashes and it worked. Please explain to me how this worked. I tried but i just appended zeroes without backslash. I'm very curious. – Anil Kumar Nov 06 '19 at 12:11
  • @Topaco Also, post an answer, i'll accept it. – Anil Kumar Nov 06 '19 at 12:11

0 Answers0