【发布时间】:2017-12-26 08:56:19
【问题描述】:
由于不推荐使用 Mcrypt,我想在我的代码中使用 OpenSSL,因为我们已经在我们的服务器中使用 php 7.0.17 并且不知道他们何时升级它。
某些第三方 API(可能托管在 PHP 5.x 上并使用 mcrypt)正在获取加密数据。他们提供了用于加密/解密字符串的方法。
他们在这里
$secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c' ;
public function encrypt128($str)
{
$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 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);
}
使用这些方法字符串small1如果加密变成v7IXp5vVaFVXXlt/MN8BVw==
我们想在我们这边使用openssl_encrypt,这样如果我们用 OpenSSL 加密相同的字符串,它必须给出与 Mcrypt 相同的结果。我研究了使用 rijndael-128 模式 ecb 的 mcrypt 应该与 OpenSSL aes-128-ecb 兼容。
在过去的几个小时里,我一直在尝试制作自己的方法来使用 OpenSSL 加密提供相同结果的字符串。到目前为止,我已经来到了这个
public function sslEncrypt128($str)
{
$secret = 'a0a7e7997b6d5fcd55f4b5c32611b87c';
return base64_encode(openssl_encrypt($str, 'aes-128-ecb', $secret, OPENSSL_RAW_DATA));
}
但它产生不同的字符串SxJ3+EdaeItZx3/EwGTUbw== 与上述输入相同。不知道是flag的问题还是padding的问题,欢迎指点。
我这里添加了代码在线测试https://3v4l.org/v2J2N
提前致谢。
【问题讨论】:
-
ECB 模式存在一些严重的安全问题。 非常确保它适合您的特定应用。一般CBC模式或CTR模式会更安全。请参阅Electronic Codebook 以获取问题的说明(字面意思)。
-
注意:Base64 数据对计算机来说很好,但对于开发人员来说,从数据中理解任何东西都需要按字节表示,十六进制满足这种需求,而 Base64 则不然。
-
在您的代码示例中,通过将
aes-128-ecb更改为aes-256-ecb,我能够在 sslEncrypt128 中产生相同的输出。 -
谢谢@MichaelButler。它解决了我的问题。
MCRYPT_RIJNDAEL_128和MCRYPT_MODE_ECB模式与打开 sslaes-256-ecb相同。您可以将您的发现作为答案发布,我会接受。
标签: php encryption cryptography mcrypt php-openssl