_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才能正常进行解密