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