How to convert mcrypt_crypt to openssl_crypt?
P粉287345251
P粉287345251 2023-09-09 17:35:02
0
1
602

I would like to improve a certain WordPress plugin that uses the now obsolete "mcrypt". Instead, I want to use the OpenSSL library to encrypt the submitted data, but during the encryption process I have problems, namely: the openssl_encrypt function returns a different value than mcrypt_encrypt, the system I am connected to does not return my data with the correct value, and Its owner cannot send me a log of the content I uploaded to it :(

I've searched the entire internet but haven't found a solution yet. I suspect the problem is with the padding, but I can't find a solution. can you help?

The following is the obvious change inside my PHP objects $password, $salt and $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);

}
}

Forgot to mention: OPENSSL_ZERO_PADDING returns error. Using OPENSSL_RAW_DATA I can get similar results to mcrypt_encrypt but with a different ending, for example:

OpenSSL: rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG+VPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8WcNzMJ868026TkUxcYJMrQ==

MCRYPT:rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG+VPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8UGVfF091Q9bY61mTRg+BSg==

P粉287345251
P粉287345251

reply all(1)
P粉021854777

In encryptSSL(), Base64 encoding is currently used twice, once explicitly and once implicitly by default. Therefore, one of the Base64 encodings, whether explicit or implicit, must be removed. The former is achieved by removing the base64_encode() call, the latter is achieved by setting the OPENSSL_RAW_DATA flag.

Additionally, mcrypt uses zero padding and PHP/OpenSSL uses PKCS#7 padding. Therefore, in order for encryptSSL() to give the same results as encryptMCRYPT(), zero padding must be used. Since PHP/OpenSSL does not support zero padding, PKCS#7 padding must be disabled (using the OPENSSL_ZERO_PADDING flag) and zero padding must be implemented explicitly>.

overall:

$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 

and:

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

With these changes, both functions give the same results.

Note that zero padding is less reliable than PKCS#7 padding.


safety:

Please note that static IVs and static salts are bugs. Instead, both will be randomly generated and passed to the decryption party along with the ciphertext, usually in concatenation (neither is secret).

Also, the number of iterations of PBKDF2 of 100 is usually too small.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template