admin管理员组

文章数量:1794759

php与java联调的aes加解密

php与java联调的aes加解密

php与java使用aes128位加密通信  

问题:联调时候发现php的解密解析不了java加密后的东西,解出来发现时乱码,当时就崩溃了,,奇了怪了,看了这篇文章,我真的是要醉了。。。。。。。。。。最后附上了php类库,留作以后备用。

问题:使用Java默认的AES加密方式(Cipher.getInstance("AES"))并对加密后结果进行Base64编码,这样php(phpaes/使用这里免费的AES实现版本

)里可以成功进行解密。而在Php加密后的字符串无法在Java中成功解密。

   1.Java中AES加密与解密默认使用AES/ECB/PKCS5Padding模式;

   2.php中的AES算法实现使用AES/ECB/NoPadding

要注意特定的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);     } }

本文标签: 加解密PHPjavaAES