php与java联调的aes加解密


PHP与JAVA使用AES128位加密通信  

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

问题:使用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和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);
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值