由于mcrypt_encrypt的函数在PHP7中已经被废弃,在之前的项目中有一个加密函数需要转换,代码如下:
$encryptString = 'lensuntop encrypt';
$key = pack('H*', "bfdecc6724cc96548fb653fa965588c");
$iv = pack('H*', "404ad092ac31fb6b5bb956ad2943259c");
$rnd = (int)(microtime(true) * 1000) ^ rand();
$rnd_text = pack("V", $rnd);
$packet = $rnd_text . "\0\0\0\0" . "en" . "\0" . $encryptString ;
$crc32 = crc32($packet);
$crc32_text = pack("V", $crc32);
$packet = $rnd_text . $crc32_text . "en" . "\0" . $encryptString ;
$result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $packet, MCRYPT_MODE_CFB, $iv);
现在要保存mcrypt_encrypt函数加密下和新函数openssl_encrypt的加密一致。搜索了一下发现有不少人遇到了我一样的问题。在stackoverflow找到了两个答案
2、https://stackoverflow.com/questions/45218465/mcrypt-rijndael-128-to-openssl-aes-128-ecb-conversion
这两个答案都是可以的。作为便捷我直接拷贝一下以上两位的代码:
代码1:
$message = "Lorem ipsum";
$key = "123456789012345678901234";
$iv = "12345678";
$message_padded = $message;
if (strlen($message_padded) % 8) {
$message_padded = str_pad($message_padded, strlen($message_padded) + 8 - strlen($message_padded) % 8, "\0");
}
$encrypted_mcrypt = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);
$encrypted_openssl = openssl_encrypt($message_padded, "DES-EDE3-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);
printf("%s => %s\n", bin2hex($message), bin2hex($encrypted_mcrypt));
printf("%s => %s\n", bin2hex($message_padded), bin2hex($encrypted_openssl));
代码2:
class EncryptHelper {
public static function encrypt128($str) {
$secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c';
$block = mcrypt_get_block_size("rijndael_128", "ecb");
$pad = $block - (strlen($str) % $block); $str .= str_repeat(chr($pad), $pad);
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $secret, $str, MCRYPT_MODE_ECB));
}
public static function decrypt128($str) {
$str = base64_decode($str);
$str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $secret, $str, MCRYPT_MODE_ECB);
$len = strlen($str); $pad = ord($str[$len - 1]);
return substr($str, 0, strlen($str) - $pad);
}
public static function sslEncrypt128($str) {
$secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c';
return base64_encode(openssl_encrypt($str, 'aes-256-ecb', $secret, OPENSSL_RAW_DATA));
}
}
printf("%s\n", EncryptHelper::encrypt128('lensuntop encrypt'));
printf("%s\n", EncryptHelper::sslEncrypt128('lensuntop encrypt'));
可惜的是我的项目中加密并不是和这两位的一样。但是既然他们能替换成一样的,自然在我的项目中也能找到解决方案。通过观察是函数中使用的加密算法不一样。通过PHP的官网 http://php.net/manual/en/function.openssl-get-cipher-methods.php 找到了所有的加密算法。如下图:
由于我的函数中使用到的是 MCRYPT_RIJNDAEL_128 和 MCRYPT_MODE_CFB 在代码2中MCRYPT_RIJNDAEL_128 对应的是aes,而且代码2中将加密字符进行了转换,所有在openssl_encrypt使用 aes-256-ecb 却可以将其加密。那么对于我项目中用到了 MCRYPT_RIJNDAEL_128 和 MCRYPT_MODE_CFB 。那么对应的应该是 AES-128-CFB、AES-128-CFB1、AES-128-CFB8或者是AES-256-CFB、AES-256-CFB1、AES-256-CFB8。在输入AES-128-CFB8后发现两个函数加密出来的字符串是一样的。到此问题解决!
由于时间的关系,我并没有深入去了解每个算法的不一样,也没有去看源代码进行对比mcrypt_encrypt和openssl_encrypt两个函数之间的区别。希望通过这些描述能够帮助到和我一样懒的人解决这个头疼的问题。毕竟我忙活了我一天的时间去耐心找到答案。