問題:使用Java默認的AES加密方式(Cipher.getInstance("AES"))並對加密后結果進行Base64編碼,這樣php(http://phpaes.com/使用這里免費的AES實現版本
)里可以成功進行解密。而在Php加密后的字符串無法在Java中成功解密。
1.Java中AES加密與解密默認使用AES/ECB/PKCS5Padding模式;
2.php中的AES算法實現使用AES/ECB/NoPadding
要注意特定的Padding實現跟算法的blockSize有關,這里php的blocksize是16。在php的aes加密前先對源字符串進行Padding,問題得到解決。
前面提到Java默認的AES加密在php 的上述aes實現中可以成功解密。其實該php解密雖然看上去是成功的,其實里面還是有些問題的。因為解密出來的字符串因為Java端加密時會padding操作,php解密以后padding的字符沒有被去掉導致會出現問題。因此解密時需要removePaddingStr才能得到原始的字符串。
代碼參考:http://blog.csdn.net/cctcc/article/details/54926947
/**
* 手機號加密
*/
private function phoneEncode($phone)
{
$key = 'abcdefgh1234567890';
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
$iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$padding = $size - (strlen($phone) % $size);
$phone_padding = $phone . str_repeat(chr($padding), $padding);
mcrypt_generic_init($td, $key, $iv);
$cyper_text = mcrypt_generic($td, $phone_padding);
$result = strtoupper(bin2hex($cyper_text));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $result;
}
/**
* 手機號解密
*/
private function phoneDecode($phone)
{
$key = 'abcdefgh1234567890';
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
$iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$text = mdecrypt_generic($td, hex2bin($phone));
$pad = ord($text{strlen($text) - 1});
$phone = substr($text, 0, -1 * $pad);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $phone;
}