福哥须要在php里利用AES加密解密功能,本日整理出来和大家分享一下。

早期的PHP实现AES借助的是mcrypt扩展,后来在PHP7之后就换成了openssl扩展来实现了。
mcrypt版本代码比较繁芜且须要自己实现PKCS7补位的逻辑,而openssl版本则默认利用了PKCS7补位不须要自己来编写代码实现了。

2. 通过openssl实现

2.1 安装openssl扩展

php补位在PHP里实现AES的加密解密功效包含mcrypt版本和openssl版本 PHP

须要安装php扩展openssl,详细方法就不供应了,php的扩展的安装办法都一样,php7.1以上的版本支持了openssl模块。

2.2 加密解密工具

加密解密工具,默认 AES-256-CBC 方法。

classAES_Encrypt{constBLOCK_SIZE=32;privatestring$method;publicfunction__construct(string$method=null){if($method==null){$method="AES-256-CBC";}$this-&gt;method=$method;}publicfunctionpkcs7Pad($str){$len=mb_strlen($str,'8bit');$c=16-($len%16);$str.=str_repeat(chr($c),$c);return$str;}privatefunctionpkcs7Encode($text){$text_length=strlen($text);$amount_to_pad=AES_Encrypt::BLOCK_SIZE-($text_length%AES_Encrypt::BLOCK_SIZE);if($amount_to_pad==0){$amount_to_pad=AES_Encrypt::BLOCK_SIZE;}$pad_chr=chr($amount_to_pad);$tmp="";for($index=0;$index<$amount_to_pad;$index++){$tmp.=$pad_chr;}return$text.$tmp;}privatefunctionpkcs7Decode($text){$pad=ord(substr($text,-1));if($pad<1||$pad>32){$pad=0;}returnsubstr($text,0,(strlen($text)-$pad));}publicfunctionencrypt(string$data,string$key,string$iv):string{$data=$this->pkcs7Encode($data);$encrypted=openssl_encrypt($data,$this->method,$key,OPENSSL_ZERO_PADDING,$iv);return$encrypted;}publicfunctiondecrypt(string$data,string$key,string$iv):string{$decrypted=openssl_decrypt($data,$this->method,$key,OPENSSL_ZERO_PADDING,$iv);$data=$this->pkcs7Decode($decrypted);return$data;}}

2.3 options

openssl_encrypt和openssl_decrypt的第三个参数是options,它有着很主要的浸染,我们来理解一下。

0:默认模式,自动进行 pkcs7 补位,同时自动进行 base64 编码1:OPENSSL_RAW_DATA,自动进行 pkcs7 补位, 但是不自动进行 base64 编码2:OPENSSL_ZERO_PADDING,须要自己进行 pkcs7 补位,同时自动进行 base64 编码3. 通过mcrypt实现

3.1 安装mcrypt扩展

须要安装php扩展mcrypt,详细方法就不供应了,php的扩展的安装办法都一样,php7.1以下的版本支持mcrypt模块。

3.2 加密解密工具

加密解密工具,默认 AES-128-CBC 方法。

classAES_Encrypt{constBLOCK_SIZE=32;private$RIJNDAEL;private$MODE;publicfunction__construct($method=null){if($method==null){$method="AES-128-CBC";}$this->RIJNDAEL=null;$this->MODE=null;$this->methodArr=explode("-",$method);switch($this->methodArr[1]){case"128":$this->RIJNDAEL=MCRYPT_RIJNDAEL_128;break;case"192":$this->RIJNDAEL=MCRYPT_RIJNDAEL_192;break;case"256":$this->RIJNDAEL=MCRYPT_RIJNDAEL_256;break;}switch($this->methodArr[2]){case"CBC":$this->MODE=MCRYPT_MODE_CBC;break;case"CFB":$this->MODE=MCRYPT_MODE_CFB;break;case"ECB":$this->MODE=MCRYPT_MODE_ECB;break;case"NOFB":$this->MODE=MCRYPT_MODE_NOFB;break;case"OFB":$this->MODE=MCRYPT_MODE_OFB;break;case"STREAM":$this->MODE=MCRYPT_MODE_STREAM;break;}if($this->RIJNDAEL==null||$this->MODE==null){thrownewException("invalidRIJNDAELorMODEabout'".$method."'",2000100);}}publicfunctionpkcs7Pad($str){$len=mb_strlen($str,'8bit');$c=16-($len%16);$str.=str_repeat(chr($c),$c);return$str;}privatefunctionpkcs7Encode($text){$text_length=strlen($text);$amount_to_pad=AES_Encrypt::BLOCK_SIZE-($text_length%AES_Encrypt::BLOCK_SIZE);if($amount_to_pad==0){$amount_to_pad=AES_Encrypt::BLOCK_SIZE;}$pad_chr=chr($amount_to_pad);$tmp="";for($index=0;$index<$amount_to_pad;$index++){$tmp.=$pad_chr;}return$text.$tmp;}privatefunctionpkcs7Decode($text){$pad=ord(substr($text,-1));if($pad<1||$pad>32){$pad=0;}returnsubstr($text,0,(strlen($text)-$pad));}publicfunctionencrypt($data,$key,$iv){$data=$this->pkcs7Encode($data);$encrypted=mcrypt_encrypt($this->RIJNDAEL,$key,$data,$this->MODE,$iv);$based_encrypted=base64_encode($encrypted);return$based_encrypted;}publicfunctiondecrypt($data,$key,$iv){$data=base64_decode($data);$encrypted=mcrypt_decrypt($this->RIJNDAEL,$key,$data,$this->MODE,$iv);$encrypted=$this->pkcs7Decode($encrypted);return$encrypted;}}4. 利用

利用AES加密须要原数据、AES私钥、令牌,下面给出一个例子。

把稳:在openssl版本里的AES-256-CBC方法对应mcrypt版本里的AES-128-CBC,也是微信"大众年夜众号做事器接口利用的AES算法的方法

4.1 示例

准备一个字符串,加密后再解密,末了如果和原字符串相同,证明函数事情正常。

$dataOrg="我是福哥,Ilikecoding!!!";$AESKey="rN6LfP9qbILPabc938IixdFds3s5ksIqjcPyYxOPx4v";$iv="";//初始化$myAES_Encrypt=newAES_Encrypt();//加密字符串$dataEncrypted=$myAES_Encrypt->encrypt($dataOrg,$AESKey,$iv);//解密字符串$dataDecrypted=$myAES_Encrypt->decrypt($dataEncrypted,$AESKey,$iv);//比较var_dump($dataOrg==$dataDecrypted);5. 总结

福哥本日给出了两个利用PHP实现AES的加密算法功能的方法,新版本的openssl效率更高、代码更大略,福哥推举这种方法~~

https://m.tongfu.net/home/35/blog/512693.html