如何将 mcrypt_encrypt 转换为 openssl_encrypt?

问题描述 投票:0回答:1

我想改进某个使用现已过时的“mcrypt”的 wordpress 插件。相反,我想使用 OpenSSL 库来加密提交的数据,但在加密过程中我遇到了问题,即:openssl_encrypt 函数返回的值与 mcrypt_encrypt 不同,我连接到的系统不会返回我正确的数据,它的所有者无法向我发送我上传到它的日志:(

我已经在互联网上搜索了整个互联网,但还没有找到解决方案。我怀疑问题是填充,但我找不到解决方案。你能帮忙吗?

下面是我的 PHP 对象 $password 的内部,$salt 和 $iv 明显改变了

class EncryptDebug{
private $algo = 'sha1';
private $password = 'ab4232goodcf423484422c90c3e4aa7c';
private $salt = 'ascastas54490a31';
private $iv = '8947da32awl55kwj'
private $lenght = 16;
private function generate_key(){
    return hash_pbkdf2( $this->algo , $this->password , $this->salt, 100, $this->lenght, true );
}
public function encryptSSL($plaintext){
    $key = $this->generate_key();
    $ciphertext = base64_encode(openssl_encrypt($plaintext, 'AES-128-CBC', $key,  OPENSSL_ZERO_PADDING, $this->iv));
    
    return str_replace('+', '%2B', $ciphertext);

}
public function encryptMCRYPT($plaintext){
    $key = $this->generate_key();
    $ciphertext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $this->iv));
    
    return str_replace('+', '%2B', $ciphertext);

}
}

忘记提及:OPENSSL_ZERO_PADDING 返回错误。使用 OPENSSL_RAW_DATA 我能够得到类似于 mcrypt_encrypt 的结果,但结尾不同,例如:

OpenSSL:rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG%2BVPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8WcNzMJ868026TkUxcYJMrQ==

MCRYPT:rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG%2BVPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8UGVfF091Q9bY61mTRg%2BBSg==

php openssl mcrypt
1个回答
0
投票

encryptSSL()
中,它目前是Base64编码两次,一次是显式的,一次是默认隐式的。因此,必须删除一种 Base64 编码,无论是显式编码还是隐式编码。前者是通过去掉
base64_encode()
调用来实现的,后者是通过设置
OPENSSL_RAW_DATA
标志来实现的。

此外,mcrypt 使用零填充,PHP/OpenSSL 使用 PKCS#7 填充。因此,为了使

encryptSSL()
给出与
encryptMCRYPT()
相同的结果,必须使用零填充。由于 PHP/OpenSSL 不支持零填充,因此必须禁用 PKCS#7 填充(使用
OPENSSL_ZERO_PADDING
标志)并且必须显式实现零填充.

整体:

$ciphertext = openssl_encrypt($this->zeroPad($plaintext, 16), 'AES-128-CBC', $key,  OPENSSL_ZERO_PADDING, $this->iv); // remove base64_encode(), zero pad plaintext, disable PKCS#7 padding 

与:

protected function zeroPad($text, $bs) {
    $pad = $bs - strlen($text) % $bs;
    return ($pad < 16) ? $text .  str_repeat("\0", $pad) : $text;
}

通过这些更改,两个函数给出相同的结果。

请注意,与 PKCS#7 填充相比,零填充是不可靠的。


安全:

请注意,静态 IV 和静态盐是漏洞。相反,两者都将随机生成并与密文一起传递给解密方,通常是连接起来的(两者都不是秘密的)。

此外,PBKDF2 的 100 次迭代次数通常太小了。

© www.soinside.com 2019 - 2024. All rights reserved.