Archive

Archive for the ‘php’ Category

How to make java share a secret with php…

May 8th, 2010 Chris Hane No comments

We have an external API that can be called from any programming language. In this day and age, who doesn’t. For a couple of the calls we have some parts that use encryption within the message. When we original designed the system, we did for internal consumption only. Now we are going back and opening those parts up to external users. Yeah! However, this is where the fun starts.

For the encryption, we use the Cipher: AES/ECB/PKCS5Padding

One of our clients uses php for their application and couldn’t figure out how to do the encryption/decryption with this particular cipher. So I got to explorer php encryption today. The popular mcrypt function seems to be what everyone uses with php. It’s built in, so no surprise there.

The difficult part is padding is not supported. There is some information out in the ether, but nothing seems to put it all together for us. So here is a quick primer.

This php program will take a message and a key and produce an encrypted string which matches our java implementation:

<?php
echo "\n";
 
function hex2bin($hexdata) {
  $bindata = "";
 
  for ($i = 0; $i < strlen($hexdata); $i += 2) {
    $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
  }
 
  return $bindata;
}
function pkcs5_pad ($text, $blocksize){
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr($pad), $pad);
}
 
function pkcs5_unpad($text){
    $pad = ord($text{strlen($text)-1});
    if ($pad > strlen($text)) return false;
    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
    return substr($text, 0, -1 * $pad);
}
function encrypt($str, $key) {
  $key = hex2bin($key);
  $td = mcrypt_module_open("rijndael-128", "", "ecb", "");
  mcrypt_generic_init($td, $key, "0000000000000000");
  $size = mcrypt_get_block_size('rijndael-128', 'ecb');
  $str = pkcs5_pad($str, $size);
  $encrypted = mcrypt_generic($td, $str);
 
  mcrypt_generic_deinit($td);
  mcrypt_module_close($td);
 
  return bin2hex($encrypted);
}
 
echo encrypt("4", "ERT345");
 
echo "\n";
?>

The key points are:
1) we have to pad the message ourselves in encryption function (or remove it from the decrypted string)
2) the IV needs to be 16 0s (or 32 if using 256bit encryption)
3) AES is refered to as rijndael in php
4) we have to translate the key using hex2bin

The above function matches what we do in java:

Key secretKey = new SecretKeySpec(fromHex(key),"AES");
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey);
String encryptedMessage = toHex(aesCipher.doFinal(message.getBytes()));

While short and sweet, it actually is not the most straight forward thing to do in php. Dam padding :) . Anyway, hope this helps someone someday.

 
Categories: Java, php