PHP与JAVA使用AES128位加密通信  

问题:联调时候发现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);
     }
 }