0

I created a Helper function for encrypt data with OpenSSL in PHP.

private const METHOD = 'AES-256-CFB';
private const KEY = 'g5(Mt2-2x=wsS8^K';

public static function encrypt($data) {
    $crypted = openssl_encrypt($data, self::METHOD, self::KEY, 1, substr(hash('sha256', self::KEY_1), 0, 16));
    return base64_encode($crypted);
}

For decrypt the AES-CFB-256 data in Java, i've made a Helper class too.

private String decrypt(String sdata) throws Exception {
    String sKey = "g5(Mt2-2x=wsS8^K";

    byte[] key = sKey.getBytes();
    byte[] iv = Arrays.copyOfRange(hash("SHA-256", key).getBytes(), 0, 16);
    byte[] data = Base64.getDecoder().decode(sdata.getBytes());

    Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
    SecretKey aesSecret = new SecretKeySpec(key, "AES");
    IvParameterSpec ivps = new IvParameterSpec(iv);

    cipher.init(Cipher.DECRYPT_MODE, aesSecret, ivps);
    byte[] result = cipher.doFinal(data);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < result.length; i++) {
        sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
    }

    System.out.println(new String(result, StandardCharsets.UTF_8) + " : " + sb.toString());
    return sb.toString();
}

private String hash(String type, byte[] data) throws Exception {
    MessageDigest digest = MessageDigest.getInstance(type);
    data = digest.digest(data);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < data.length; i++) {
        sb.append(Integer.toString((data[i] & 0xff) + 0x100, 16).substring(1));
    }

    return sb.toString();
}

I noticed that the hash function in JAVA works and gives me the same result as the hash function in PHP. The problem is that the result of the cipher is totally different and I don't see were is the mistake.

Thanks for your help

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125

1 Answers1

1

After few test, Java appear to use AES-128 instead of AES-256.
If I modify this part of the PHP code.

private const METHOD = 'AES-256-CFB';

To this

private const METHOD = 'AES-128-CFB';

Java and PHP return the same result now.
I hope that it will help

  • Another option would be to leave `'AES-256-CFB'` in the PHP encryption and change the Java cipher transformation to `"AES_256/CFB/NoPadding"`. Note that the key would then need to be 32 bytes (256 bits) to match the AES bit length. PHP appears to "helpfully" let you specify keys that are shorter than the algorithm needs. – msbit Aug 19 '18 at 02:11
  • Java is using AES-128 because the key provided has 16 bytes (=128b). – gusto2 Aug 19 '18 at 05:08
  • @gusto2 Thanks but after providing a key of 32 bytes, the result does not match either. Thanks msbit, does PHP padding the key ? –  Aug 19 '18 at 17:07
  • there are some other questions like that and indeed php is padding the key which I find not really intuitive. – gusto2 Aug 19 '18 at 21:20