1. 程式人生 > >PHP利用openssl整理AES加解密類

PHP利用openssl整理AES加解密類

<?php
/**
 * Created by PhpStorm.
 * User: nassir
 * Date: 2017/12/11
 * Time: 15:25
 */

namespace Ryanc\RSA;


class AES
{
    private $_cipher;// 加密方式
    private $_key;// 金鑰
    private $_options = 0;// options 是以下標記的按位或: OPENSSL_RAW_DATA 、 OPENSSL_ZERO_PADDING
    private $_iv = '';// 非null的初始化向量
    private $_tag = '';// 使用 AEAD 密碼模式(GCM 或 CCM)時傳引用的驗證標籤
    private $_aad = '';// 附加的驗證資料
    private $_tagLength = 16;// 驗證 tag 的長度。GCM 模式時,它的範圍是 4 到 16

    public function __construct( string $cipher, string $key, int $options = 0, string $iv = '', string $tag = null, string $add = '', int $tagLength = 16)
    {
        $this->_cipher = $cipher;
        $this->_options = $options;
        $this->_tag = $tag;
        $this->_aad = $add;
        $this->_tagLength = $tagLength;
        $ivlen = openssl_cipher_iv_length($cipher);// 獲得該加密方式的iv長度
        $this->_iv = openssl_random_pseudo_bytes($ivlen);// 生成相應長度的偽隨機位元組串作為初始化向量
        $this->_key = $key . 'nassir';
    }

    public function encrypt($plaintext)
    {
        $ciphertext = openssl_encrypt($plaintext, $this->_cipher, $this->_key, $this->_options, $this->_iv, $this->_tag);
        return $ciphertext;
    }

    public function decrypt($ciphertext)
    {
        $original_plaintext = openssl_decrypt($ciphertext, $this->_cipher, $this->_key, $this->_options, $this->_iv, $this->_tag);
        return $original_plaintext;
    }
}

$tmp = new AES("aes-128-gcm", "123456789WANGchao");
$plaintext = "message to be encrypted";
$ciphertext = $tmp->encrypt($plaintext);
echo $ciphertext . "\n";
$original_plaintext = $tmp->decrypt($ciphertext);
echo $original_plaintext . "\n";

程式碼如上,需要說一下AES這種對稱加密原理也沒記清,只記得它的安全基於位元組替換、行排序、列混淆、迴圈加密,是常用對稱加密方式之一(對稱加密主要就AES、DES、3DES),感興趣的自己搜一下AES原理,我這裡只說一下這個函式中可能不懂的地方。

常見的AES加密方法有ECB,CTR,GMAC,GCM,相同之處都是:明文分組->加密->密文分組。不同之處在於:
ECB的加密是單純的明文分支與金鑰進行加密運算,也就是說會出現有著相同明文的不同分組加密後有一樣的密文分組,這一點很容易被針對從而破解出金鑰
CTR加密過程引入計數器概念,沒一輪加密後執行一次計數器改變金鑰,從而擺脫ECB的缺陷。不夠這個方式需要一個初始計數器的值,也就是 $iv
GMAC 加密過程引入MAC(訊息驗證碼)來保證訊息的完整性,需要一個附加訊息與密文一起生成MAC值
GCM G是GMAC C是CTR 兩者綜合

由此個人理解,php實現aes-gcm加密的方法如下

string openssl_encrypt ( string $data , string $method , string $key [, int $options = 0 [, string $iv = "" [, string &$tag = NULL [, string $aad = "" [, int $tag_length = 16 ]]]]] )

$data 待加密明文

$method 所使用的加密方法(包括但不限於AES這幾種)

$key 金鑰

$vi 初始向量,在gcm中做初始計數器提高保證加密的安全性

tag,aad,tag_length都是為了保證加密中資料的完整性而存在的,具體作用還待研究。

更新

忽然發現tag用於驗證訊息完整性是可變的,在進行解密時要有密文與加密中被修改了的tag才能正常進行解密