官方宣布PHP5.6过不了多久要停止维护了,所以今年第一季度做过一些升级PHP7.X的准备,使用PHP7.2对项目做了一次回归测试,发现我们项目受升级影响的主要是一些函数摒弃了,或有了其他函数替代。
     例如:create_function 直接摒弃了、mcrypt摒弃了,但可以使用openssl做兼容等等。
     这篇主要讲一下mcrypt怎么使用openssl代替并兼容老代码。

mcrypt与openssl替换对应表

mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv)
openssl_encrypt($data, 'AES-128-CBC', $key, 0, $iv)

*不同的的明文块大小对应就好(分别支持128、192、256),值得注意的是,mcrypt_encrypt输出内容是二进制,展示需要base64加密,openssl_encrypt的第四个参数option可选择是否以二进制输出等,也可设置直接base64输出结果,具体参数详情请去官网自行查看

浅分析原理

AES加密大概原理图如下:
v2-543a90bc665cc47df293985fa652a445_hd.jpg

mcrypt_encrypt的第一个参数和openssl_encrypt第二个参数中的数字就表示明文块大小,所以当$data的长度不是指定明文块的整数倍的时候需要进行padding填充,使原始明文是指定明文块大小的整数倍。一般默认是简单粗暴的在后面补0(二进制)。至于CBC模式,是指明文块之间的关系,不是指不同的加密算法依然是AES加密算法,具体请查询文章最后的参考链接。

有些时候会自己先padding,比如pkcs5、pkcs7等

/**
 * 基本原理请参考:
 * http://en.wikipedia.org/wiki/Padding_(cryptography)
 */
function pkcs5_pad($text, $blocksize)
{
    $pad = $blocksize - (strlen($text) % $blocksize);
    return $text . str_repeat(chr($pad), $pad);
}

function pkcs5_unpad($text)
{
    $pad = ord($text{strlen($text) - 1});
    if ($pad > strlen($text)) return false;
    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
    return substr($text, 0, -1 * $pad);
}

参考文章

L https://zhuanlan.zhihu.com/p/45155135
https://www.chilkatsoft.com/p/php_aes.asp