PHP & Java interoperable encryption
by ricardoz on Jan.16, 2009, under Articles, Security, Tips
I recently faced the problem of encrypting something in PHP and decrypting it using Java, this proved to be a little more of a challenge than what it initially seemed like.
In any case, the secret layed in the padding, Java uses by default a PCKS5 padding algorithm and PHP does not.
Here is a sample of the code you need to encrypt something (to later on decrypt it using Java) using PHP and mcrypt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | function pkcs5_pad ($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } function encrypt($key, $text){ // Pack and pad $keyPacked = pack('H*',utf8_encode($key)); $input = pkcs5_pad(pack('H*', utf8_encode($text)), 8); // Init mcrypt $td = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'ecb', ''); $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); mcrypt_generic_init($td, $keyPacked, $iv); // Execute the encryption algorithm $encrypted_data = mcrypt_generic($td, $input); // Cleanup mcrypt_generic_deinit($td); mcrypt_module_close($td); // Return a nice hex formatted string return bin2hex($encrypted_data); } |
A small extra, if you want to decrypt something encrypted using Java DESede algorithm and coded in base 64 (the most usual output format), you can use the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function decrypt($key, $data) { $keyHex = bin2hex(base64_decode($key)); $dataHex = bin2hex(base64_decode($data)); $keyPacked = pack('H*',utf8_encode($keyHex)); $input = pkcs5_pad(pack('H*', utf8_encode($dataHex)), 8); $td = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'ecb', ''); $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); mcrypt_generic_init($td, $keyPacked, $iv); $decrypted_data = mdecrypt_generic($td, $input); mcrypt_generic_deinit($td); mcrypt_module_close($td); return $decrypted_data; } |
September 11th, 2009 on 9:44 am
I am currently facing the same issue as above but I can not get the example to work. It may be for different reasons. Here is the complete code that I need to decrypt this text of as a beta test:
<?php
function decrypt($key, $data) {
$keyHex = bin2hex(base64_decode($key));
$dataHex = bin2hex(base64_decode($data));
$keyPacked = pack(’H*’,utf8_encode($keyHex));
$input = pkcs5_pad(pack(’H*’, utf8_encode($dataHex)), 8);
$bit_check=8;
$text_num =str_split($input,$bit_check);
$text_num = $bit_check-strlen($text_num[count($text_num)-1]);
for ($i=0;$i<$text_num; $i++) {$input = $input . chr($text_num);}
$td = mcrypt_module_open(MCRYPT_DES, ”, ‘ecb’, ”);
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $keyPacked, $iv);
$decrypted_data = mdecrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $decrypted_data;
}
function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize – (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
$mkey = “NynpHBZblyo=”;
$mtoken = “8iy4HCksTc1FbwV7WkYj7mDnHPEa6Frj”;
$plaintextc = decrypt($mkey,$mtoken);
echo “”;
echo $plaintextc;
?>
Here is the output:
8,”�n�Gmѭ-�B��嬼�}R#v��M�iaG�
Do you have any ideas? This is DES and not TRIPLEDES.
September 14th, 2009 on 8:16 am
Michael, how did you come up with the encrypted data? Are you sure you are using PKCS5 on the encrypting end?