php 如何将mcrypt_encrypt转换为openssl_encrypt?

hmmo2u0o  于 2023-05-05  发布在  PHP
关注(0)|答案(1)|浏览(126)

我想改进某个使用现在已经过时的“mcrypt”的wordpress插件。相反,我想使用OpenSSL库来加密提交的数据,但在加密过程中我遇到了问题,即:openssl_encrypt_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%2BVPdcz5iKAAkAwrDTTFTcOpWgWOCh9l9JFZ8UGVfF091Q9bY61mTRg%2BBSg ==

rggaifut

rggaifut1#

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和静态salt是漏洞。相反,两者都是随机生成的,并与密文沿着传递到解密端,通常是级联的(两者都不是秘密的)。
此外,PBKDF 2的迭代计数100通常太小。

相关问题