搜尋
首頁後端開發php教程PHP7.1中使用openssl取代mcrypt 的介紹

這篇文章主要介紹了關於PHP7.1中使用openssl替換mcrypt 的介紹,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

#PHP7.1中使用openssl替換mcrypt

在php開發中,使用mcrypt相關函數可以很方便地進行AES加、解密操作,但是PHP7.1中廢棄了mcrypt擴展,所以必需尋找另一種實現。在遷移手冊中已經指出了用openssl取代mcrypt,但未給出具體範例。網路上有許多範例,可以替換大部分場景,但對於其中細節卻並未說明。同樣,簡單地使用網路範例在某種程式碼場景下有可能導致程式碼替換前後的相容問題,以下則來談談具體程式碼及原因。

首先我們直接給出替換的程式碼,再從程式碼分析問題。 (本文分析的演算法是AES-128-CBC)

替換範例

範例會展示兩種mcrypt的使用方式,主要在於填充不同(下文會解釋填充)。在整個加、解密過程中,完整程度高一點程式碼則會自主實現填充、移除填充,簡單一點程式碼會直接忽略填充,但兩種方式都可以正常運作;在實際開發中(7.1之前版本),建議加上填充。請看如下具體範例:

  1. mcrypt未使用填充

  • mcrypt加密:

      $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);
  • #相同功能的openssl加密代碼:

      $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));
  • mcrypt使用填充

    • mcrypt加密:

        $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);
    • 相同功能的openssl加密程式碼:

        $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));

    以上範例皆可成功運行,其中第一個範例(未使用填充,但在openssl中進行了填充)和第二個範例(使用填充,在openssl中未使用填充)在替換前後輸出相同,並無相容問題。大家可以依照程式碼不同的填滿方式來選擇不同的替換方案,但其中有三個細節需要說明

    1. 為什麼要有填滿?

    2. 用openssl取代後演算法的名稱為何不同?

    接下來會則會具體分析 填充演算法

    填充

    為什麼有填充則要從加密的演算法說起。因為在AES-128-CBC演算法中,會把要加密的字串以每16個byte的長度進行分段,逐步計算,由此導致不足16byte的段則會進行填充。所以給出的範例中會有兩種:一種是使用預設的填充,另一種是自主填充。在與openssl的替換中,如何選擇填充方案,則需要對mcrypt與openssl針對預設與自主填充有所了解。

    • mcrypt預設填入

      在php的原始碼中,可以看出預設會以\x00進行填充,事實上,並非是以\x00進行填充,從原始碼中可以發現,首先申請了一個16位元的空字串,所以初始化時每位位元組均為\x00, 實際上可以說其中並沒有填充,只是它本來就是\x00 ,使用預設填充得到的加密字串會是如下形式:
      PHP7.1中使用openssl取代mcrypt 的介紹

      所以解密時則要移除多餘的\x00。當然也可以懶一點,不要移除\x00。因為在php中字串"string\x00"與字串"string"除了長度不一樣外,其他表現一致,所以看起來並無區別,如下程式碼:

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

      \x00 填滿後的範例:(請注意字串的長度,由此可見以\x00填滿會影響長度)
      PHP7.1中使用openssl取代mcrypt 的介紹

    • mcrypt自主填充

      填充演算法需以以下演算法進行:

      • #加入填充

          /**
           * 填充算法
           * @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;
          }

        加入填充後字串實際上如下形式:
        PHP7.1中使用openssl取代mcrypt 的介紹

      • 移除填充

          /**
           * 移去填充算法
           * @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;
          }
    • openssl預設填入

      其默認方式與標準的mcrypt的自主填充方式一致,所以在第二個範例中,對於使用瞭如上的填充演算法後, 可直接使用openssl_encrypt替換,不會產生相容問題。填充後的加密字串如下形式:

      PHP7.1中使用openssl取代mcrypt 的介紹

      要注意的是在openssl_encryptopenssl_decrypt中內建了填充與移除填充,所以直接使用即可,除非需自主實作填充,否則不需要考慮填充

    • openssl自主填充

      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));

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

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

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

    • 示例2:
      mcrypt加密时使用了标准的填充,同时openssl的填充方式也为PHP7.1中使用openssl取代mcrypt 的介紹,故直接使用即可。

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

    选择算法

    在以上的示例中,有一个问题在于,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添加文章固定字段的介绍

    以上是PHP7.1中使用openssl取代mcrypt 的介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    哪些常見問題會導致PHP會話失敗?哪些常見問題會導致PHP會話失敗?Apr 25, 2025 am 12:16 AM

    PHPSession失效的原因包括配置錯誤、Cookie問題和Session過期。 1.配置錯誤:檢查並設置正確的session.save_path。 2.Cookie問題:確保Cookie設置正確。 3.Session過期:調整session.gc_maxlifetime值以延長會話時間。

    您如何在PHP中調試與會話相關的問題?您如何在PHP中調試與會話相關的問題?Apr 25, 2025 am 12:12 AM

    在PHP中調試會話問題的方法包括:1.檢查會話是否正確啟動;2.驗證會話ID的傳遞;3.檢查會話數據的存儲和讀取;4.查看服務器配置。通過輸出會話ID和數據、查看會話文件內容等方法,可以有效診斷和解決會話相關的問題。

    如果session_start()被多次調用會發生什麼?如果session_start()被多次調用會發生什麼?Apr 25, 2025 am 12:06 AM

    多次調用session_start()會導致警告信息和可能的數據覆蓋。 1)PHP會發出警告,提示session已啟動。 2)可能導致session數據意外覆蓋。 3)使用session_status()檢查session狀態,避免重複調用。

    您如何在PHP中配置會話壽命?您如何在PHP中配置會話壽命?Apr 25, 2025 am 12:05 AM

    在PHP中配置會話生命週期可以通過設置session.gc_maxlifetime和session.cookie_lifetime來實現。 1)session.gc_maxlifetime控制服務器端會話數據的存活時間,2)session.cookie_lifetime控制客戶端cookie的生命週期,設置為0時cookie在瀏覽器關閉時過期。

    使用數據庫存儲會話的優點是什麼?使用數據庫存儲會話的優點是什麼?Apr 24, 2025 am 12:16 AM

    使用數據庫存儲會話的主要優勢包括持久性、可擴展性和安全性。 1.持久性:即使服務器重啟,會話數據也能保持不變。 2.可擴展性:適用於分佈式系統,確保會話數據在多服務器間同步。 3.安全性:數據庫提供加密存儲,保護敏感信息。

    您如何在PHP中實現自定義會話處理?您如何在PHP中實現自定義會話處理?Apr 24, 2025 am 12:16 AM

    在PHP中實現自定義會話處理可以通過實現SessionHandlerInterface接口來完成。具體步驟包括:1)創建實現SessionHandlerInterface的類,如CustomSessionHandler;2)重寫接口中的方法(如open,close,read,write,destroy,gc)來定義會話數據的生命週期和存儲方式;3)在PHP腳本中註冊自定義會話處理器並啟動會話。這樣可以將數據存儲在MySQL、Redis等介質中,提升性能、安全性和可擴展性。

    什麼是會話ID?什麼是會話ID?Apr 24, 2025 am 12:13 AM

    SessionID是網絡應用程序中用來跟踪用戶會話狀態的機制。 1.它是一個隨機生成的字符串,用於在用戶與服務器之間的多次交互中保持用戶的身份信息。 2.服務器生成並通過cookie或URL參數發送給客戶端,幫助在用戶的多次請求中識別和關聯這些請求。 3.生成通常使用隨機算法保證唯一性和不可預測性。 4.在實際開發中,可以使用內存數據庫如Redis來存儲session數據,提升性能和安全性。

    您如何在無狀態環境(例如API)中處理會議?您如何在無狀態環境(例如API)中處理會議?Apr 24, 2025 am 12:12 AM

    在無狀態環境如API中管理會話可以通過使用JWT或cookies來實現。 1.JWT適合無狀態和可擴展性,但大數據時體積大。 2.Cookies更傳統且易實現,但需謹慎配置以確保安全性。

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    Video Face Swap

    Video Face Swap

    使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

    熱工具

    ZendStudio 13.5.1 Mac

    ZendStudio 13.5.1 Mac

    強大的PHP整合開發環境

    SublimeText3 英文版

    SublimeText3 英文版

    推薦:為Win版本,支援程式碼提示!

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    將Eclipse與SAP NetWeaver應用伺服器整合。

    WebStorm Mac版

    WebStorm Mac版

    好用的JavaScript開發工具