首頁 >後端開發 >php教程 >資料加密解密

資料加密解密

一朵云彩
一朵云彩原創
2020-05-06 17:55:57183瀏覽

隨著PHP版本升級,有些函數已經廢棄,例如加密和解密函數,在PHP7.1之前,透過mcrypt_decrypt()和mcrypt_encrypt()實作解密和加密,在PHP7.1之後透過openssl_decrypt()和openssl_encrypt ()實現解密和加密。在此,透過封裝類,將兩種實作的方式實作

兩種方式的加密解密步驟:

解密時傳回原始資料(數組—->加密—->加密字串—->解密—->原始數組|| JSON字串—->加密—->加密字串—->解密—->原始JSON字符字串|| 字串—->加密—->加密字串—->解密—->原始字串)

PHP7.1以下使用

類別方法

該類別中需要注意的是金鑰: 演算法所對應的key 長度:AES-128, 192 and 256 的加密key 的長度分別為16, 24和32 位元

<?php
namespace aes;
class AesT
{
    private $_bit = MCRYPT_RIJNDAEL_256;
    private $_type = MCRYPT_MODE_CBC;
    private $_key = &#39;ThisIsYourAesKey&#39;; // 密钥 必须16位 24位  32位
    private $_use_base64 = true;
    private $_iv_size = null;
    private $_iv = null;

    /**
     * @param string $_key 密钥
     * @param int $_bit 默认使用128字节  支持256、192、128
     * @param string $_type 加密解密方式  默认为ecb 支持cfb、cbc、nofb、ofb、stream、ecb
     * @param boolean $_use_base64 默认使用base64二次加密
     */
    public function __construct($_key = &#39;&#39;, $_bit = 128, $_type = &#39;ecb&#39;, $_use_base64 = true)
    {
        // 加密字节
        if (192 === $_bit) {
            $this->_bit = MCRYPT_RIJNDAEL_192;
        } elseif (128 === $_bit) {
            $this->_bit = MCRYPT_RIJNDAEL_128;
        } else {
            $this->_bit = MCRYPT_RIJNDAEL_256;
        }
        // 加密方法
        if (&#39;cfb&#39; === $_type) {
            $this->_type = MCRYPT_MODE_CFB;
        } elseif (&#39;cbc&#39; === $_type) {
            $this->_type = MCRYPT_MODE_CBC;
        } elseif (&#39;nofb&#39; === $_type) {
            $this->_type = MCRYPT_MODE_NOFB;
        } elseif (&#39;ofb&#39; === $_type) {
            $this->_type = MCRYPT_MODE_OFB;
        } elseif (&#39;stream&#39; === $_type) {
            $this->_type = MCRYPT_MODE_STREAM;
        } else {
            $this->_type = MCRYPT_MODE_ECB;
        }
        // 密钥
        if (!empty($_key)) {
            $this->_key = $_key;
        }
        // 是否使用base64
        $this->_use_base64 = $_use_base64;

        $this->_iv_size = mcrypt_get_iv_size($this->_bit, $this->_type);
        $this->_iv = mcrypt_create_iv($this->_iv_size, MCRYPT_RAND);
    }

    /**
     * 加密
     * @param string $string 待加密字符串
     * @return string
     */
    public function encode($string)
    {
        //
        if (MCRYPT_MODE_ECB === $this->_type) {
            $encodeString = mcrypt_encrypt($this->_bit, $this->_key, json_encode($string), $this->_type);
        } else {
            $encodeString = mcrypt_encrypt($this->_bit, $this->_key, json_encode($string), $this->_type, $this->_iv);
        }
        if ($this->_use_base64) {
            $encodeString = base64_encode($encodeString);
        }
        return $encodeString;
    }

    /**
     * 解密
     * @param string $string 待解密字符串
     * @return string
     */
    public function decode($string)
    {
        if ($this->_use_base64) {
            $string = base64_decode($string);
        }
        if (MCRYPT_MODE_ECB === $this->_type) {
            $decodeString = mcrypt_decrypt($this->_bit, $this->_key, $string, $this->_type);
        } else {
            $decodeString = mcrypt_decrypt($this->_bit, $this->_key, $string, $this->_type, $this->_iv);
        }
      return $decodeString;
    }
}

使用

<?php
use aes\AesT;
class Test{
	public function index()
    {
        $data1 = [&#39;status&#39; => &#39;1&#39;, &#39;info&#39; => &#39;success&#39;, &#39;data&#39; => [[&#39;id&#39; => 1, &#39;name&#39; => &#39;大房间&#39;, &#39;2&#39; => &#39;小房间&#39;]]];
        //$data2 = &#39;{"status":"1","info":"success","data":[{"id":1,"name":"\u5927\u623f\u95f4","2":"\u5c0f\u623f\u95f4"}]}&#39;;
        //$data3 = &#39;PHP AES cbc模式 pkcs7 128加密解密&#39;;
        $objT = new AesT();
        $resT = $objT->encode($data1);//加密数据
        var_dump($resT);
        var_dump($objT->decode($resT));//解密
    }
}

#PHP7.1以上使用

##############################################################

類別方法

#AES-128-CBC, AES-192-CBC和AES-256-CBC 的加密key 的長度分別為16, 24 和32 位元


openssl_encrypt()的四個參數中,需要注意的是第四個參數:

0 : 自動對明文進行padding, 傳回的資料經過base64 編碼.

##1 : OPENSSL_RAW_DATA, 自動對明文進行padding,但傳回的結果未經過base64 編碼.

2 : OPENSSL_ZERO_PADDING, 自动对明文进行 0 填充, 返回的结果经过 base64 编码

<?php

namespace aes;

class Aes
{
    public static $key = &#39;&#39;;
    public static $iv = &#39;&#39;;
    public static $method = &#39;&#39;;

    public function __construct()
    {
        //加密key
        self::$key = md5(&#39;AeSNJkBfhHmJqLzHL&#39;, true);
        //保证偏移量为16位
        self::$iv = md5(&#39;HfgUdCliBjKjuRfa&#39;, true);
        //加密方式  # AES-128-CBC AES-192-CBC AES-256-CBC
        self::$method = &#39;AES-128-CBC&#39;;
    }

    /**
     * @desc 加密
     * @param $data
     * @return false|string
     */
    public function aesEn($data)
    {
        return base64_encode(openssl_encrypt(json_encode($data), self::$method, self::$key, OPENSSL_RAW_DATA, self::$iv));
    }

    /**
     * @desc 解密
     * @param $data
     * @return false|string
     */
    public function aesDe($data)
    {
        $tmpData = openssl_decrypt(base64_decode($data), self::$method, self::$key, OPENSSL_RAW_DATA, self::$iv);
        return is_null(json_decode($tmpData)) ? $tmpData : json_decode($tmpData, true);
    }
}

使用

<?php

use aes\Aes;

class Test
{
    public function aes()
    {
        $obj = new Aes();
		
        $data = [&#39;status&#39; => &#39;1&#39;, &#39;info&#39; => &#39;success&#39;, &#39;data&#39; => [[&#39;id&#39; => 1, &#39;name&#39; => &#39;大房间&#39;, &#39;2&#39; => &#39;小房间&#39;]]];
        //$data = &#39;{"status":"1","info":"success","data":[{"id":1,"name":"\u5927\u623f\u95f4","2":"\u5c0f\u623f\u95f4"}]}&#39;;
        //$data = &#39;PHP AES cbc模式 pkcs7 128加密解密&#39;;
        $res = $obj->aesEn($data);//加密数据
        var_dump($res);
        var_dump($obj->aesDe($res));//解密
    }
}


使用该加密解密类时,如果将两个类整合到一个类中,需要通过PHP_VERSION获取当前PHP版本

以上是資料加密解密的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn