Comment convertir mcrypt_crypt en openssl_crypt ?
P粉287345251
P粉287345251 2023-09-09 17:35:02
0
1
592

Je souhaite améliorer un certain plugin WordPress qui utilise le désormais obsolète « mcrypt ». Au lieu de cela, je souhaite utiliser la bibliothèque OpenSSL pour crypter les données soumises, mais pendant le processus de cryptage, je rencontre des problèmes, à savoir : la fonction openssl_encrypt renvoie une valeur différente de celle de mcrypt_encrypt, le système auquel je suis connecté ne renvoie pas mes données avec le bon valeur, et son propriétaire ne peut pas m'envoyer un journal du contenu que j'y ai téléchargé :(

J'ai cherché sur tout Internet mais je n'ai pas encore trouvé de solution. Je soupçonne que le problème vient du rembourrage, mais je ne trouve pas de solution. peux-tu aider ?

Voici les changements évidents dans mes objets PHP $password, $salt et $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);

}
}

J'ai oublié de mentionner : OPENSSL_ZERO_PADDING renvoie une erreur. En utilisant OPENSSL_RAW_DATA, je peux obtenir des résultats similaires à mcrypt_encrypt mais avec une fin différente, par exemple :

OpenSSL : rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG%2BVPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8WcNzMJ868026TkUxcYJMrQ==

MCRYPT : rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG%2BVPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8UGVfF091Q9bY61mTRg%2BBSg==

P粉287345251
P粉287345251

répondre à tous(1)
P粉021854777

Obtenu avec le drapeau encryptSSL() 中,当前使用 Base64 编码两次,默认情况下一次是显式编码,一次是隐式编码。因此,必须删除其中一种 Base64 编码,无论是显式编码还是隐式编码。前者是通过删除 base64_encode() 调用来实现的,后者是通过设置 OPENSSL_RAW_DATA.

De plus, mcrypt utilise un remplissage nul et PHP/OpenSSL utilise un remplissage PKCS#7. Par conséquent, afin d’obtenir le même résultat que encryptSSL() 给出与 encryptMCRYPT() , un remplissage nul doit être utilisé. Puisque PHP/OpenSSL ne prend pas en charge le remplissage zéro, le remplissage PKCS#7 doit être désactivé (en utilisant l'indicateur OPENSSL_ZERO_PADDING) et le remplissage zéro doit être implémenté explicitement >.

Global :

$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 

avec :

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

Avec ces changements, les deux fonctions donnent les mêmes résultats.

Veuillez noter que le remplissage zéro est moins fiable que le remplissage PKCS#7.


Sécurité :

Veuillez noter que les IV statiques et les sels statiques sont des bugs. Au lieu de cela, les deux seront générés aléatoirement et transmis à l'équipe de décryptage avec le texte chiffré, généralement sous forme de concaténation (aucun des deux n'est secret).

De plus, le nombre d'itérations de PBKDF2 est de 100, ce qui est généralement trop petit.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!