php如何openssl_encrypt加密解密

最近在對接客戶的CRM系統,獲取令牌時,要用DES方式加密解密,因爲以前沒有搞錯這種加密方式,通過請教了「百度」和「谷歌」兩個老師後,結合了多篇文檔內容後,終於實現了。php

1、DES介紹

DES 是對稱性加密裏面常見一種,全稱爲 Data Encryption Standard,即數據加密標準,是一種使用密鑰加密的塊算法。密鑰長度是64位(bit),超過位數密鑰被忽略。所謂對稱性加密即加密和解密密鑰相同,對稱性加密通常會按照固定長度,把待加密字符串分紅塊,不足一整塊或者恰好最後有特殊填充字符。html

  • 跨語言作 DES 加密解密常常會出現問題,每每是填充方式不對、編碼不一致或者加密解密模式沒有對應上形成。
  • 常見的填充模式有: pkcs五、pkcs七、iso1012六、ansix92三、zero。
  • 加密模式有:DES-ECB、DES-CBC、DES-CTR、DES-OFB、DES-CFB。

加密用到的方法:

openssl_encrypt($data, $method, $password, $options, $iv)

參數說明:算法

  1. $data 加密明文
  2. $method 加密方法編程

    • DES-ECB
    • DES-CBC
    • DES-CTR
    • DES-OFB
    • DES-CFB
  3. $passwd 加密密鑰[密碼]
  4. $options 數據格式選項(可選)【選項有:】swoole

    • 0
    • OPENSSL_RAW_DATA=1
    • OPENSSL_ZERO_PADDING=2
    • OPENSSL_NO_PADDING=3
  5. $iv 密初始化向量(可選)
  • 須要注意:若是$method爲DES-ECB,則$iv無需填寫

2、解密用到的方法:

openssl_decrypt($data, $method, $password, $options, $iv)

參數說明:php7

  1. $data 要解密的數據
  2. 其餘參數同加密方法

3、用法案例:

參數:app

$data = '1234567887654321';//加密明文
   $method = 'DES-ECB';//加密方法
   $passwd = '12344321';//加密密鑰
   $options = 0;//數據格式選項(可選)
   $iv = '';//加密初始化向量(可選)

(1) 默認填充方式:

    • 加密:編程語言

      $result = openssl_encrypt($data, $method, $passwd, $options);
      var_dump($result);

      結果:工具

      string(32) "kQYOdswcm9I5elv2wdJucplqAgqDNqXg"
    • 解密測試

      $result = 'kQYOdswcm9I5elv2wdJucplqAgqDNqXg';
      var_dump(openssl_decrypt($result, $method, $passwd, 0));

      結果:

      string(16) "1234567887654321"

    (2) OPENSSL_RAW_DATA方式【會用PKCS#7進行補位】

    • 加密

      $result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA);
      var_dump($result);

      結果:

      string(24) "�v���9z[���nr�j �6��"

      咱們能夠看到結果是亂碼的,這時咱們須要base64一下

      $result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA);
      var_dump(base64_encode($result));

      這時結果是

      string(32) "kQYOdswcm9I5elv2wdJucplqAgqDNqXg"
    • 解密

      result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA);
      
      var_dump(openssl_decrypt($result, $method, $passwd,OPENSSL_RAW_DATA));

      結果:

      string(16) "1234567887654321"

      咱們能夠看到:默認填充方式與OPENSSL_RAW_DATA,這兩種方式加密結果是同樣的

    (3) OPENSSL_ZERO_PADDING方式

    看字面意思,是用0填充,可是測試並不起做用

    • 加密

      $result = openssl_encrypt($data, $method, $passwd, OPENSSL_ZERO_PADDING);
      var_dump($result);

      結果:

      string(24) "kQYOdswcm9I5elv2wdJucg=="
    • 解密:

      $result = openssl_encrypt($data, $method, $passwd, OPENSSL_ZERO_PADDING);
      var_dump(openssl_decrypt($result, $method, $passwd,OPENSSL_ZERO_PADDING));

      結果:

      string(16) "1234567887654321"

    (4) OPENSSL_NO_PADDING【不填充,須要手動填充】

    • 在openssl_encrypt前加上填充過程
    • 加密

      $str_padded = $data;
        if (strlen($str_padded) % 16) {
            $str_padded = str_pad($str_padded,strlen($str_padded) + 16 - strlen($str_padded) % 16, "\0");
        }
        $result = openssl_encrypt($str_padded, $method, $passwd, OPENSSL_NO_PADDING);
        var_dump($result);
        echo '<br>';
        var_dump( base64_encode($result));

      結果:

      string(16) "�v���9z[���nr" 
      string(24) "kQYOdswcm9I5elv2wdJucg=="

      咱們能夠看到結果是加密的亂碼,須要用base64一下,就能夠看到結果了

    • 解密:

      //加密begin
        $str_padded = $data;
        if (strlen($str_padded) % 16) {
            $str_padded = str_pad($str_padded,strlen($str_padded) + 16 - strlen($str_padded) % 16, "\0");
        }
        $result = openssl_encrypt($str_padded, $method, $passwd, OPENSSL_NO_PADDING);
        //加密end
       //解密begin
       $str = base64_encode($result);
       $m = openssl_decrypt( base64_decode($str) , $method, $passwd, OPENSSL_NO_PADDING);
       var_dump( rtrim( rtrim( $m,chr(0) ), chr(7) ) );
       //解密 end

      結果:

      string(16) "1234567887654321"

    ** 結尾要去除填充字符’0’和’a’。
    ‘a’是爲了兼容用OPENSSL_RAW_DATA加密的結果。 **

    參照的文檔有:

    相關知識文章

    相關文章
    相關標籤/搜索