2

I have recently used the AES algorithm in Java in order to cipher a text. Now I need to rebuild that algorithm in PHP, but I have no idea how, because PHP algorithms on the internet return different results. Maybe you can help me.

This is the Java-code to encrypt:

private static final String KEY = "57238004e784498bbc2f8bf984565090";

public static String encrypt(final String plaintext) throws GeneralSecurityException {
    SecretKeySpec sks = new SecretKeySpec(hexStringToByteArray(KEY), "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, sks, cipher.getParameters());
    byte[] encrypted = cipher.doFinal(plaintext.getBytes());
    return byteArrayToHexString(encrypted);
}

public static byte[] hexStringToByteArray(String s) {
    byte[] b = new byte[s.length() / 2];
    for (int i = 0; i < b.length; i++) {
        int index = i * 2;
        int v = Integer.parseInt(s.substring(index, index + 2), 16);
        b[i] = (byte) v;
    }
    return b;
}

public static String byteArrayToHexString(byte[] b) {
    StringBuilder sb = new StringBuilder(b.length * 2);
    for (int i = 0; i < b.length; i++) {
        int v = b[i] & 0xff;
        if (v < 16) {
            sb.append('0');
        }
        sb.append(Integer.toHexString(v));
    }
    return sb.toString().toUpperCase();
}

Can you guys possibly help me with building a PHP script, that returns the same results?

Example: The plaintext "STACKOVERFLOW" is encrypted to "FA652ECCDC39A11A93D2458AA2A0793C".

Thanks in advance!

3
  • ECB is not secure. You need to use CBC, and pass an IV. Depending on your security boundaries, you probably also need authenticated encryption, such as GCM. Commented Jul 24, 2013 at 13:41
  • The problem is, I am not allowed to alter the Java-code. Commented Jul 24, 2013 at 13:55
  • This might be of interest: phpclasses.org/package/… Commented Jul 24, 2013 at 14:02

1 Answer 1

3

This should do it:

function encrypt($plaintext, $key) {
    $plaintext = pkcs5_pad($plaintext, 16);
    return bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, hex2bin($key), $plaintext, MCRYPT_MODE_ECB));
}

function decrypt($encrypted, $key) {
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, hex2bin($key), hex2bin($encrypted), MCRYPT_MODE_ECB);
    $padSize = ord(substr($decrypted, -1));
    return substr($decrypted, 0, $padSize*-1);
}

function pkcs5_pad ($text, $blocksize)
{
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr($pad), $pad);
}

The reason that other PHP algorithms you found were returning different results is likely because of the padding. The default for AES in Java is PKCS5, but PHP doesn't have native support for this (hence the pkcs5_pad function).

As SLacks has said, you really should not be using ECB though. Either get the Java code changed or re-encrypt your existing data if need be. As long as you continue using ECB, you're putting your data at risk.

Credit: Padding function taken from here.

Sign up to request clarification or add additional context in comments.

3 Comments

Could you give me the decrypt-php-function, too? And thanks so much! It works.
Added per your request.
Awesome work, Syon! Both cryptic functions gave me the same result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.