问题:联调时候发现php的解密解析不了java加密后的东西,解出来发现时乱码,当时就崩溃了,,奇了怪了,看了这篇文章,我真的是要醉了。。。。。。。。。。最后附上了php类库,留作以后备用。
问题:使用Java默认的AES加密方式(Cipher.getInstance("AES"))并对加密后结果进行Base64编码,这样php(http://phpaes.com/使用这里免费的AES实现版本
)里可以成功进行解密。而在Php加密后的字符串无法在Java中成功解密。
要注意特定的Padding实现跟算法的blockSize有关,这里php的blocksize是16。在php的aes加密前先对源字符串进行Padding,问题得到解决。
--------------------------------------------------------------------------------------------------
本来JAVA和JSP之间加密通信好好的,相同的函数,相同的处理,不会有其他大问题。不过有时候就是蛋疼啊,于是就有了PHP与JAVA间使用AES进行加密通信。 PHP的AES128位由mcrypt模块提供,称为MCRYPT_RIJNDAEL_128。 JAVA的AES默认就是128位的。 加密模式有好几种,不同的语言不同的库支持的情况不同。这里选择的是安全且通用的CBC模式。 至于padding,这是最头疼的问题,因为PHP的padding与Java的padding不一样。如果使用NoPadding,则默认又用不了 CBC模式。所以,最好的解决方法是自己padding——在原文末尾加上若干个空格,使原文凑齐16的倍数的长度。当然,原文末尾也可能是空格结束啊, 那怎么办?没办法,只有强制原文末尾加上一个换行。这样子,每次解密后,将最右边的换行以及其右边的空格裁剪掉,就得到原文了。 另外,为了兼容,在加密和解密时,需要将内容转换成16进制的字符数组。这样一来,即使加密/解密的内容不是普通文本,而是二进制数据,也可以轻松传送啦。
附:php aes类库
<?php
class AesDe{
const SHA1 = 'SHA1';
const CBC = 'cbc';
const CIPHER = 'rijndael-128';
const BLOCKSIZE = 128;
const HASH_ITERATIONS = 10000;
const KEY_LENGTH = 32;
//偏移变量
private $arrIv = array(0xA, 1, 0xB, 5, 4, 0xF, 7, 9, 0x17, 3, 1, 6, 8, 0xC, 0xD, 91);
//salt 值
private $arrSalt = array(1, 3, 9, 6, 9, 4, 4, 4, 0, 2, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF);
public function aes($ostr, $aes_key, $type='encrypt'){
if($ostr==''){
return '';
}
//只能用128解密,虽然大地的demo是256
$td = mcrypt_module_open(self::CIPHER, '', self::CBC, '');
//不能用随机的iv
$iv = self::genIV();
$salt = self::genSalt();
$key = self::pbkdf2(self::SHA1, $aes_key, $salt, self::HASH_ITERATIONS, self::KEY_LENGTH);
mcrypt_generic_init($td, $key, $iv);
$str = '';
switch($type){
case 'encrypt':
$str = trim(base64_encode(mcrypt_generic($td, $this->pkcs5Pad($ostr))));
break;
case 'decrypt':
$str = trim(mdecrypt_generic($td, base64_decode($ostr)));
break;
}
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $str;
}
private function pbkdf2($algorithm, $password, $salt, $count, $key_length) {
$algorithm = strtolower($algorithm);
if(!in_array($algorithm, hash_algos(), true)){
trigger_error('PBKDF2 ERROR: Invalid hash algorithm.', E_USER_ERROR);
}
if($count <= 0 || $key_length <= 0) {
trigger_error('PBKDF2 ERROR: Invalid parameters.', E_USER_ERROR);
}
$hash_length = strlen(hash($algorithm, "", true));
$block_count = ceil($key_length / $hash_length);
$output = "";
for($i = 1; $i <= $block_count; $i++) {
$last = $salt . pack("N", $i);
$last = $xorsum = hash_hmac($algorithm, $last, $password, true);
for ($j = 1; $j < $count; $j++) {
$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
}
$output .= $xorsum;
}
return substr($output, 0, $key_length);
}
private function genIV() {
$iv = '';
foreach($this->arrIv as $value) {
$iv .= chr($value);
}
return $iv;
}
private function genSalt() {
$salt = '';
foreach($this->arrSalt as $value) {
$salt .= chr($value);
}
return $salt;
}
private function pkcs5Pad($data) {
$blockSize = mcrypt_get_block_size(self::CIPHER, self::CBC);
$pad = $blockSize - (strlen($data) % $blockSize);
return $data . str_repeat(chr($pad), $pad);
}
}