mcrypt 替代为 openssl

最近想将php5.6升级到php7.2,翻阅兼容性文档,发现mcrypt已被移除,官方建议用openssl代替,原先项目用到mcrypt,于是进行替换测试。

$key = '1234567890123456';   //16字节
$iv = '1234567890123456';    //16字节
$str = 'abcdefg测试密文......';

原加密代码:

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_CBC, $iv);
var_dump(base64_encode($encrypted)) ;

替换代码

$encrypted = openssl_encrypt($str, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);
var_dump(base64_encode($encrypted)) ;

同样的key和iv结果竟然不同

string(44) “iOjsba+z8aP9JBLGzl5qyby3doyqLbgmggExPt6Z8Go=”
string(44) “iOjsba+z8aP9JBLGzl5qyZAa7Usw/KSBWndy+ypyPDs=”

翻阅大量文档,得出点结论
1.mcrypt加密前默认对原文进行padding,padding方式是用0填充
2.openssl的option有三个选项:
OPENSSL_RAW_DATA 会用PKCS#7进行补位
OPENSSL_ZERO_PADDING 看字面意思,是用0填充,但是测试并不起作用,有了解的希望解答一下
OPENSSL_NO_PADDING 不填充,需要手动填充
3.如果要让openssl的加密结果和原先的mcrypt一样,必须要手动用0填充,然后再用openssl加密

再次测试,在openssl_encrypt前加上填充过程

$str_padded = $str;
if (strlen($str_padded) % 16) {
  $str_padded = str_pad($str_padded,strlen($str_padded) + 16 - strlen($str_padded) % 16, "\0");
}
$encrypted = openssl_encrypt($str_padded, 'aes-128-cbc', $key, OPENSSL_NO_PADDING , $iv);
var_dump( base64_encode($encrypted));

结果一致,如下

string(44) “iOjsba+z8aP9JBLGzl5qyby3doyqLbgmggExPt6Z8Go=”

解密就简单的多了,直接把openssl的option设为OPENSSL_NO_PADDING就可以了

$decrypted =openssl_decrypt( base64_decode($str) , 'aes-128-cbc', $key, OPENSSL_NO_PADDING, $iv);
var_dump( rtrim( rtrim( $decrypted,chr(0) ), chr(7) ) );

结尾要去除填充字符’\0’和’\a’。
‘\a’是为了兼容用OPENSSL_RAW_DATA加密的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值