1、DES介紹
DES 是對稱性加密里面常見一種,是一種使用密鑰加密的塊算法。密鑰長度是64位(bit),超過位數密鑰會被忽略。
a、跨語言做 DES 加密解密經常會出現問題,往往是填充方式不對、編碼不一致或者加密解密模式沒有對應上造成。
b、常見的填充模式有: pkcs5、pkcs7、iso10126、ansix923、zero。
c、加密模式有:DES-ECB、DES-CBC、DES-CTR、DES-OFB、DES-CFB。
2、加密方法
openssl_encrypt($data, $method, $password, $options, $iv)
參數說明:
$data 加密明文
$method 加密方法
1、DES-ECB
2、DES-CBC
3、DES-CTR
4、DES-OFB
5、DES-CFB
$passwd 加密密鑰[密碼]
$options 數據格式選項(可選)【選項有:】
1、0
2、OPENSSL_RAW_DATA=1
3、OPENSSL_ZERO_PADDING=2
4、OPENSSL_NO_PADDING=3
$iv 密初始化向量(可選)
3、解密方法
openssl_decrypt($data, $method, $password, $options, $iv)
參數說明:
- $data 要解密的數據
- 其他參數同加密方法
4、用法案例
參數:
$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方式
//加密 $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加密的結果。 **
示例用法
class Aes { public $key = ''; public $iv = ''; public function __construct($config) { foreach($config as $k => $v){ $this->$k = $v; } } //加密 public function aesEn($data){ return base64_encode(openssl_encrypt($data, $this->method,$this->key, OPENSSL_RAW_DATA , $this->iv)); } //解密 public function aesDe($data){ return openssl_decrypt(base64_decode($data), $this->method, $this->key, OPENSSL_RAW_DATA, $this->iv); } } $config = [ 'key' => 'reter4446fdfgdfgdfg', //加密key 'iv' => md5(time(). uniqid(),true), //保證偏移量為16位 'method' => 'AES-128-CBC' //加密方式 # AES-256-CBC等 ]; $obj = new Aes($config); $res = $obj->aesEn('aaaddee44');//加密數據 echo $res; echo '<hr>'; echo $obj->aesDe($res);//解密
注:以上文章部份摘抄自 php如何openssl_encrypt加密解密,文章地址:https://blog.csdn.net/zhemejinnameyuanxc/article/details/83383434