Maison  >  Article  >  développement back-end  >  Comment utiliser OpenSSL au lieu du cryptage et du décryptage Mcrypt en PHP ?

Comment utiliser OpenSSL au lieu du cryptage et du décryptage Mcrypt en PHP ?

php中世界最好的语言
php中世界最好的语言original
2017-12-20 14:37:191718parcourir

Récemment, j'ai découvert un problème lors du développement d'un compte officiel WeChat, c'est-à-dire que PHP7.1 est obsolète dans mcrypt, je ne peux donc que trouver un moyen de résoudre ce problème. Aujourd'hui, je vais vous expliquer comment je l'ai résolu. Ce problème et ses solutions.

Après la sortie de php7.1, les nouvelles fonctionnalités ont attiré de nombreux PHPers, et tout le monde discutait des avantages et des commodités apportées par les nouvelles fonctionnalités. Cependant, la mise à niveau de php7.0 vers php7.1 rend obsolète (obsolète) une extension qui était couramment utilisée dans le passé (extension mcrypt). Le responsable a fourni des conseils de solution correspondants, mais n'a pas fourni de solutions plus détaillées. Alors voici le piège :

Aujourd'hui, lorsque j'utilisais la plateforme ouverte WeChat pour me connecter à un système de gestion de contenu, cela échouait constamment lors de la liaison du compte officiel

Raison :

Lors du débogage, il a été constaté que la cause directe était l'événement d'autorisation renseigné dans la plateforme ouverte (l'événement d'autorisation enverra un événement toutes les dix minutes pour mettre à jour le ticket), soit :


L'URL renseignée ici, le débogage a révélé que cette URL est correcte, WeChat l'a également poussée toutes les 10 minutes, mais le ticket n'a été reçu qu'à la fin. En regardant le code, j'ai trouvé que c'était parce que. une erreur a été signalée lors du déchiffrement des données de WeChat :

<?php
  
function aes_decode($message, $encodingaeskey = &#39;&#39;, $appid = &#39;&#39;) {
 $key = base64_decode($encodingaeskey . &#39;=&#39;);
  
 $ciphertext_dec = base64_decode($message);
 $iv = substr($key, 0, 16);
  
 $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($module, $key, $iv);
 $decrypted = mdecrypt_generic($module, $ciphertext_dec);
 mcrypt_generic_deinit($module);
 mcrypt_module_close($module);
  
 $pad = ord(substr($decrypted, -1));
 if ($pad < 1 || $pad > 32) {
 $pad = 0;
 }


Voilà où c'est Comme mon environnement est PHP 7.1, j'ai cherché des informations et j'ai trouvé que PHP 7.1. a abandonné Mcrypt, donc mcrypt_* dans ce code ne peut pas être exécuté.

Solution :

Après avoir recherché des informations, j'ai trouvé que Mcrypt peut être remplacé par OpenSSL (à condition que l'extension OpenSSL ait été installée, mais elle est généralement installée par défaut)

openssl est une boîte à outils puissante qui intègre de nombreux algorithmes cryptographiques et outils pratiques. Nous pouvons utiliser l'outil de console de commande qu'il fournit pour générer des clés et des certificats pour crypter et déchiffrer les fichiers, ou nous pouvons utiliser l'interface API qu'il fournit pour crypter les informations transmises dans le code.

Le code ci-dessus peut donc être modifié en :

<?php
  
function aes_decode($message, $encodingaeskey = &#39;&#39;, $appid = &#39;&#39;) {
 $key = base64_decode($encodingaeskey . &#39;=&#39;);
  
 $ciphertext_dec = base64_decode($message);
 $iv = substr($key, 0, 16);
  
 /* mcrypt对称解密代码在PHP7.1已经被抛弃了,所以使用下面的openssl来代替
 $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($module, $key, $iv);
 $decrypted = mdecrypt_generic($module, $ciphertext_dec);
 mcrypt_generic_deinit($module);
 mcrypt_module_close($module);
 */
 $decrypted = openssl_decrypt($ciphertext_dec, &#39;AES-256-CBC&#39;, $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
  
 $pad = ord(substr($decrypted, -1));
 if ($pad < 1 || $pad > 32) {
 $pad = 0;
 }


Supplémentaire :

Ci-dessus Le décryptage a été modifié, donc le cryptage Mcrypt correspondant doit également être modifié s'il n'est pas modifié, cela entraînera des événements tels que l'impossibilité de publier sur l'ensemble du réseau et l'impossibilité de transmettre des messages
Le crypté. le code source est le suivant :

<?php
function aes_encode($message, $encodingaeskey = &#39;&#39;, $appid = &#39;&#39;) {
 $key = base64_decode($encodingaeskey . &#39;=&#39;);
 $text = random(16) . pack("N", strlen($message)) . $message . $appid;
 $iv = substr($key, 0, 16);
  
 $block_size = 32;
 $text_length = strlen($text);
 $amount_to_pad = $block_size - ($text_length % $block_size);
 if ($amount_to_pad == 0) {
 $amount_to_pad = $block_size;
 }
 $pad_chr = chr($amount_to_pad);
 $tmp = &#39;&#39;;
 for ($index = 0; $index < $amount_to_pad; $index++) {
 $tmp .= $pad_chr;
 }
 $text = $text . $tmp;
 $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
 $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($module, $key, $iv);
 $encrypted = mcrypt_generic($module, $text);
 mcrypt_generic_deinit($module);
 mcrypt_module_close($module);
  
 $encrypt_msg = base64_encode($encrypted);
 return $encrypt_msg;
}

Modification Le code final est :

<?php
function aes_encode($message, $encodingaeskey = &#39;&#39;, $appid = &#39;&#39;) {
 $key = base64_decode($encodingaeskey . &#39;=&#39;);
 $text = random(16) . pack("N", strlen($message)) . $message . $appid;
 $iv = substr($key, 0, 16);
  
 $block_size = 32;
 $text_length = strlen($text);
 $amount_to_pad = $block_size - ($text_length % $block_size);
 if ($amount_to_pad == 0) {
 $amount_to_pad = $block_size;
 }
 $pad_chr = chr($amount_to_pad);
 $tmp = &#39;&#39;;
 for ($index = 0; $index < $amount_to_pad; $index++) {
 $tmp .= $pad_chr;
 }
 $text = $text . $tmp;
 /* mcrypt对称加密代码在PHP7.1已经被抛弃了,所以使用下面的openssl来代替
 $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
 $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
 mcrypt_generic_init($module, $key, $iv);
 $encrypted = mcrypt_generic($module, $text);
 mcrypt_generic_deinit($module);
 mcrypt_module_close($module);
 */
  
 $encrypted = openssl_encrypt($text, &#39;AES-256-CBC&#39;, $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
 $encrypt_msg = base64_encode($encrypted);
 return $encrypt_msg;
}

Remarque particulière : Pour tout processus impliquant le développement de WeChat, si vous avez mis à niveau vers PHP 7.1, il est Il est nécessaire de vérifier si Mcrypt est utilisé pour le cryptage et le déchiffrement symétriques. WeChat La démo utilisée dans la documentation de développement utilise également Mcrypt pour le cryptage et le déchiffrement, ce qui nécessite une attention particulière.

Résumé

Explication de la technologie de requête asynchrone Ajax avec des exemples

Quelle est la syntaxe commune d'AJAX

Principes AJAX et méthodes inter-domaines CORS

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn