Einführung in die Verwendung von OpenSSL als Ersatz für Mcrypt in PHP7.1

不言
Freigeben: 2023-04-02 10:48:01
Original
2201 Leute haben es durchsucht

Dieser Artikel stellt hauptsächlich die Verwendung von OpenSSL als Ersatz für PHP7.1 vor. Jetzt kann ich ihn mit Ihnen teilen.

Verwenden Sie openssl, um mcrypt in PHP7.1 zu ersetzen

In der PHP-Entwicklung kann die Verwendung von mcrypt-bezogenen Funktionen problemlos AES-Verschlüsselungs- und -Entschlüsselungsvorgänge durchführen, aber die mcrypt-Erweiterung wird in PHP7.1 aufgegeben, sodass Sie eine andere finden müssen Art der Erkenntnis. Das Ersetzen von mcrypt durch openssl wird bereits im Migrationshandbuch erwähnt, es wird jedoch kein konkretes Beispiel gegeben. Es gibt online viele Beispiele, die die meisten Szenarien ersetzen können, aber die Details werden nicht erklärt. Ebenso kann die einfache Verwendung von Online-Beispielen in bestimmten Codeszenarien zu Kompatibilitätsproblemen vor und nach dem Ersetzen des Codes führen. Lassen Sie uns weiter unten über die spezifischen Codes und Gründe sprechen.

Zuerst geben wir den Ersatzcode direkt an und analysieren dann das Problem anhand des Codes. (Der in diesem Artikel analysierte Algorithmus ist AES-128-CBC)

Ersatzbeispiel

Das Beispiel zeigt zwei Möglichkeiten der Verwendung von mcrypt, hauptsächlich beim Padding Unterschiedlich (Polsterung wird weiter unten erklärt). Während des gesamten Verschlüsselungs- und Entschlüsselungsprozesses implementiert ein vollständigerer Code das Füllen und Entfernen des Füllens automatisch, und ein einfacherer Code ignoriert das Füllen direkt, aber beide Methoden können in der tatsächlichen Entwicklung normal ausgeführt werden (Versionen vor 7.1). Es wird empfohlen um Polsterung hinzuzufügen. Bitte sehen Sie sich das folgende konkrete Beispiel an:

  1. mcrypt verwendet kein Padding

  • mcrypt-Verschlüsselung:

      $key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; 
      $iv = 'aaaaaaaaaaaaaaaa';
      $data = 'dataString';
    
      $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
      mcrypt_generic_init($cipher, $key, $iv);
      $cipherText256 = mcrypt_generic($cipher, $data);
      mcrypt_generic_deinit($cipher);
    
      return bin2hex($cipherText256);
    Nach dem Login kopieren
  • Öffnet SSL-Verschlüsselungscode mit der gleichen Funktion:

      $key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; 
      $iv = 'aaaaaaaaaaaaaaaa';
      $data = 'dataString';
    
      $data = $data . str_repeat("\x00", 16 - (strlen($data) % 16)); // 双引号可以解析asc-ii码\x00
    
      return bin2hex(openssl_encrypt($data, "AES-256-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv));
    Nach dem Login kopieren
  • mcrypt verwendet Auffüllung

    • mcrypt-Verschlüsselung:

        $key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; 
        $iv = 'aaaaaaaaaaaaaaaa';
        $data = 'dataString';
      
        // 填充(移除填充反着移除即可)
        $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
      
        $pad = $block - (strlen($data) % $block);
        if ($pad <= $block) {
            $char = chr($pad);
            $data .= str_repeat($char, $pad);
        }
      
        $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, &#39;&#39;, MCRYPT_MODE_CBC, &#39;&#39;);
        mcrypt_generic_init($cipher, $key, $iv);
        $cipherText256 = mcrypt_generic($cipher, $data);
        mcrypt_generic_deinit($cipher);
      
        return bin2hex($cipherText256);
      Nach dem Login kopieren
    • OpenSSL-Verschlüsselungscode für die gleiche Funktion:

        $key = &#39;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#39;; 
        $iv = &#39;aaaaaaaaaaaaaaaa&#39;;
        $data = &#39;dataString&#39;;
      
        return bin2hex(openssl_encrypt($data, &#39;AES-256-CBC&#39;, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv));
      Nach dem Login kopieren

    Die obigen Beispiele können erfolgreich ausgeführt werden, wobei das erste Beispiel ( (kein Padding verwendet, aber mit Padding in OpenSSL) und im zweiten Beispiel (mit Padding, ohne Padding in OpenSSL) ist die Ausgabe vor und nach dem Ersetzen dieselbe und es gibt keine Kompatibilitätsprobleme. Sie können verschiedene Ersatzlösungen basierend auf den unterschiedlichen Füllmethoden des Codes auswählen, es gibt jedoch drei Details, die erklärt werden müssen

    1. Warum gibt es eine Polsterung?

    2. Warum unterscheiden sich die Namen der Algorithmen, nachdem sie durch openssl ersetzt wurden?

    Im Folgenden finden Sie eine detaillierte Analyse der Füllung und des Algorithmus.

    Padding

    Warum es Padding gibt, beginnt mit dem Verschlüsselungsalgorithmus. Denn im AES-128-CBC-Algorithmus wird die zu verschlüsselnde Zeichenfolge alle 16 Bytes in Segmente segmentiert und Schritt für Schritt berechnet, was dazu führt, dass Segmente mit weniger als 16 Bytes gefüllt werden. Daher gibt es zwei Arten von Beispielen: Zum einen wird die Standardfüllung verwendet, zum anderen wird die unabhängige Füllung verwendet. Beim Ersetzen von OpenSSL erfordert die Auswahl des Auffüllschemas Kenntnisse über die standardmäßige und autonome Auffüllung von mcrypt und OpenSSL.

    • mcrypt-Standardauffüllung

      Im Quellcode von PHP ist zu sehen, dass die Standardauffüllung mit x00 erfolgt. Tatsächlich ist sie nicht mit aufgefüllt x00 Aus dem Quellcode geht hervor, dass zuerst eine 16-Bit-Leerzeichenfolge angewendet wird, sodass jedes Byte während der Initialisierung x00 ist. Tatsächlich kann man sagen, dass es keine Auffüllung gibt, aber Es ist ursprünglich x00. Verwenden Sie die Standardeinstellung. Die aufgefüllte verschlüsselte Zeichenfolge hat die folgende Form:
      Einführung in die Verwendung von OpenSSL als Ersatz für Mcrypt in PHP7.1

      , daher muss das überflüssige x00 beim Entschlüsseln entfernt werden. Natürlich können Sie auch faul sein und x00 nicht entfernen. Da in PHP die Zeichenfolge „stringx00“ und die Zeichenfolge „string“ bis auf die Länge die gleiche Leistung haben, scheint es keinen Unterschied zu geben. Der folgende Code:

         // 尾部包含若干个`\x00` 均可功输出true
         if ("string\x00" == "string") { // 用双引号可解析\x00
             echo true;
         }
      Nach dem Login kopieren

      x00 Ausgefülltes Beispiel (Bitte Beachten Sie die Länge der Zeichenfolge. Es ist ersichtlich, dass sich das Auffüllen mit x00 auf die Länge auswirkt Algorithmus Es muss gemäß dem folgenden Algorithmus ausgeführt werden:
      Einführung in die Verwendung von OpenSSL als Ersatz für Mcrypt in PHP7.1

    • Auffüllung hinzufügen

        /**
         * 填充算法
         * @param string $source
         * @return string
         */
        function addPKCS7Padding($source)
        {
            $source = trim($source);
            $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
      
            $pad = $block - (strlen($source) % $block);
            if ($pad <= $block) {
                $char = chr($pad);
                $source .= str_repeat($char, $pad);
            }
            return $source;
        }
      Nach dem Login kopieren

      Nach dem Hinzufügen der Auffüllung hat die Zeichenfolge tatsächlich die folgende Form:

      • Auffüllung entfernen

          /**
           * 移去填充算法
           * @param string $source
           * @return string
           */
          function stripPKSC7Padding($source)
          {
              $source = trim($source);
              $char = substr($source, -1);
              $num = ord($char);
              if ($num == 62) return $source;
              $source = substr($source, 0, -$num);
              return $source;
          }
        Nach dem Login kopieren


        Einführung in die Verwendung von OpenSSL als Ersatz für Mcrypt in PHP7.1

        openssl-Standardauffüllung
      • Die Standardmethode stimmt mit überein Die standardmäßige autonome Auffüllmethode von mcrypt kann daher im zweiten Beispiel nach Verwendung des obigen Auffüllalgorithmus direkt durch openssl_encrypt ersetzt werden, ohne dass es zu Kompatibilitätsproblemen kommt. Die aufgefüllte verschlüsselte Zeichenfolge hat die folgende Form:

    • Es ist zu beachten, dass Auffüllen und Auffüllen-Entfernen in

      und

      integriert sind. also direkt Verwenden Sie es einfach. Sofern Sie das Füllen nicht unabhängig implementieren müssen, müssen Sie nicht über das Füllen nachdenken

      Einführung in die Verwendung von OpenSSL als Ersatz für Mcrypt in PHP7.1

      openssl-unabhängiges Füllen

      openssl_encrypt提供了option参数以支持自主填充,但在查阅php源码中openssl的测试用例代码才找到正确用法:

         // if we want to manage our own padding
        $padded_data = $data . str_repeat(&#39; &#39;, 16 - (strlen($data) % 16));
        $encrypted = openssl_encrypt($padded_data, $method,     $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
        $output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
        var_dump(rtrim($output));
      Nach dem Login kopieren

      (备注:如上,OPENSSL_ZERO_PADDING 并非是为0填充的意思)
      由此,我们就可以解释,在第一个示例中openssl_encrypt之前加入了自主点充\x00的代码原因了

    从以上的加、解密针对填充逻辑不同,针对上文中的示例可以很好地解释:

    • 示例1:
      mcrypt加密时未使用填充,故以\x00进行了填充,所以在替换成openssl,需要自主实现\x00填充。

    • 示例2:
      mcrypt加密时使用了标准的填充,同时openssl的填充方式也为Einführung in die Verwendung von OpenSSL als Ersatz für Mcrypt in PHP7.1,故直接使用即可。

    分析到这,可以发现,无论是何种填充策略都需注意在加密时加入填充,在解密时则必须要移除填充。至此,上文中示例中的填充相关则分析完成了,接下来我们再看看如何选择替换后的算法。

    选择算法

    在以上的示例中,有一个问题在于,mcrypt中的AES-128-CBC算法,在openssl中怎么替换成了AES_256?
    关于这一点, 我也未找到合理的解释,查看源码一时半会也没找到原因(能力有限~),但通过以下资料,还是完成了功能

    • openssl 解密 mcrypt AES 数据不兼容问题

    • Convert mcrypt_generic to openssl_encrypt Ask Question

    若是有同学找到原因,欢迎给我留言,谢谢。

    总结

    对于使用mcrypt AES 进行加密密的部分,若是在替换过程中问题, 可以从算法替换或填充这两方面着手考虑下。同时还是一必须满足的条件是根据不同的填充方式选择, 替换最重要的就要考虑兼容问题,保证替换后不发生任何改变。 虽然只是只是有细微的差别----尾部几个字符串的不同,但若是在多平台中同时进行修改也是一件麻烦事,但变动越少风险越小。

    本文只是针对AES算法进行了简单说明,对于其他算法是否适用还有待研究。

    以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

    相关推荐:

    PHP Excel导入数据到MySQL数据库的方法

    wordpress添加文章固定字段的介绍

    Das obige ist der detaillierte Inhalt vonEinführung in die Verwendung von OpenSSL als Ersatz für Mcrypt in PHP7.1. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Verwandte Etiketten:
    Quelle:php.cn
    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
    Beliebte Tutorials
    Mehr>
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage
    Über uns Haftungsausschluss Sitemap
    Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!