在 PHP 中将 mcrypt_encrypt 转换为 openssl_encrypt
Posted
技术标签:
【中文标题】在 PHP 中将 mcrypt_encrypt 转换为 openssl_encrypt【英文标题】:Converting mcrypt_encrypt to openssl_encrypt in PHP 【发布时间】:2021-09-22 06:16:41 【问题描述】:由于 mcrypt_encrypt 从 php 8 中删除,我需要将以下代码转换为使用 openssl_encrypt
function encryptValue($input,$sKey)
$key = hex2bin($sKey);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$pad = $block - (strlen($input) % $block);
$input .= str_repeat(chr($pad), $pad);
$encrypted_text = bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $input, MCRYPT_MODE_ECB));
return $encrypted_text;
我将其替换为以下内容:
function encryptData($input, $sKey)
$key= hex2bin($sKey);
$encrypted_text = bin2hex(openssl_encrypt($input, 'AES-256-ECB', $key, OPENSSL_RAW_DATA));
return $encrypted_text;
由于 openssl 做了默认填充,我没有像在原始代码中那样填充明文。我相信密钥正在转换为二进制。如果我省略了两个代码的密钥转换,那么我会得到相同的加密文本。但是如果我使用密钥转换,那么密文就不一样了。
如果我从两者中删除以下代码,则两者都返回相同的加密文本。
$key= hex2bin($sKey);
但如果没有这个,它将无法与外部 API 一起使用。
【问题讨论】:
您的代码 "$key .= chr(hexdec($sKey[$i].$sKey[$i+1]))" 是“十六进制字符串到字符串”转换器,例如输入“31323334353637386162636465666768”被转换为“12345678abcdefgh”。现在一切都取决于 key length - 使用我的示例字符串时,您有一个 16 个字符/字节长的 AES 密钥,它适用于 AES-128 而不是 AES -256 与您在函数中使用的一样。在您的 openssl 代码中使用双倍输入密钥将需要 AES-256。如果我的回答没有解决您的问题,如果您可以提供带有结果密文的示例密钥,这可能会有所帮助。$inputVal
在两个 sn-ps 中都没有定义。这必须更改为$input
。可能是复制/粘贴问题。修复此问题后,两个代码都返回相同的密文(只要两个代码一致地使用密钥转换)。顺便说一句,密钥转换在功能上与hex2bin()
相同。
@MichaelFehr 示例密钥:2ca8a887d4cc71dd68785c2ebe11a6aa 这是一个真正的密钥。这通过 hex2bin 函数,它返回一些 unicode 字符。然后将其传递给加密函数。另外,我将 AES-256-ECB 与 openssl 一起使用,因为这是密钥大小。
@user9014097 编辑了问题。不使用密钥转换时,hex2bin 都返回相同的密文。但是当两者都使用密钥转换时,密文是不同的。不知道发生了什么。并且它需要密钥转换,因为接收 API 可能也在解密中使用它。
同样在第一个 sn-p 中,将 $inputVal
更改为 $input
。目前您不使用填充明文。
【参考方案1】:
您的代码"$key .= chr(hexdec($sKey[$i].$sKey[$i+1]))"
是“十六进制字符串到字符串”转换器,例如输入“31323334353637386162636465666768”被转换为“12345678abcdefgh”。
现在一切都取决于密钥长度 - 使用我的示例字符串时,您有一个 16 个字符/字节长的 AES 密钥,适用于 AES-128 和 非 AES-256 就像你在函数中使用的那样。
在您的 openssl 代码中使用双输入密钥需要 AES-256。
如果我的回答没有解决您的问题,如果您可以提供带有结果密文的示例密钥,这可能会有所帮助。
【讨论】:
以上是关于在 PHP 中将 mcrypt_encrypt 转换为 openssl_encrypt的主要内容,如果未能解决你的问题,请参考以下文章
PHP 7.2 中 mcrypt_encrypt 的完全替代品
.NET WebService 加密 -> PHP 解密错误:mcrypt_encrypt(): IV 参数必须与块大小一样长
php使用内置的mcrypt_encrypt和mcrypt_decrypt进行字符串加密解密