AES256 in Java vs. PHP

A quick one that has so far been evading me (long night). I am comparing AES256 in PHP and Java and notice the discrepancies. Please, for simplicity, ignore the ascii key and zero IV, they will be replaced by production. But I need to go past this first and cannot understand where I am mistaken:

PHP:

echo base64_encode(
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        "1234567890ABCDEF1234567890ABCDEF",
        "This is a test",
        MCRYPT_MODE_CBC,
        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    )
);

Java

byte[] key = "1234567890ABCDEF1234567890ABCDEF".getBytes("UTF-8");
byte[] iv  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKeySpec newKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
byte[] results = cipher.doFinal("This is a test".getBytes("UTF-8"));

return Base64.encodeToString(results,Base64.DEFAULT);

PHP output: 0KwK+eubMErzDaPU1+mwTQ==

Java output: DEKGJDo3JPtk48tPgCVN3Q==

Not quite what I expected o_O!

I also tried it MCRYPT_MODE_CBC, MCRYPT_MODE_CFB, MCRYPT_MODE_ECB, MCRYPT_MODE_NOFB, etc. none of them created a Java string.

+5
source share
1 answer

PHP fills in the input bytes with \0to make it a multiple of the block size. The equivalent in Java would be like this (if the string you want to encrypt is in data):

Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
int blockSize = cipher.getBlockSize();

byte[] inputBytes = data.getBytes();
int byteLength = inputBytes.length;
if (byteLength % blockSize != 0) {
    byteLength = byteLength + (blockSize - (byteLength % blockSize));
}

byte[] paddedBytes = new byte[byteLength];

System.arraycopy(inputBytes, 0, paddedBytes, 0, inputBytes.length);

cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
byte[] results = cipher.doFinal(paddedBytes);

- . \0 . PKCS5Padding , PHP. , - , .

+1

All Articles