php如何openssl_encrypt加密解密
Published on 1周前 in PHP with 0 comment And 4614 views

php如何openssl_encrypt加密解密

in PHP with 0 comment And 4614 views

一、DES介绍

DES 是对称性加密里面常见一种,全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。密钥长度是64位(bit),超过位数密钥被忽略。所谓对称性加密即加密和解密密钥相同,对称性加密一般会按照固定长度,把待加密字符串分成块,不足一整块或者刚好最后有特殊填充字符。

  • 跨语言做 DES 加密解密经常会出现问题,往往是填充方式不对、编码不一致或者加密解密模式没有对应上造成。
  • 常见的填充模式有: pkcs5、pkcs7、iso10126、ansix923、zero。
  • 加密模式有:DES-ECB、DES-CBC、DES-CTR、DES-OFB、DES-CFB。

加密用到的方法:

 openssl_encrypt($data, $method, $password, $options, $iv)

参数说明:

  1. $data 加密明文
  2. $method 加密方法

    • DES-ECB
    • DES-CBC
    • DES-CTR
    • DES-OFB
    • DES-CFB
  3. $passwd 加密密钥[密码]
  4. $options 数据格式选项(可选)【选项有:】

    • 0
    • OPENSSL_RAW_DATA=1
    • OPENSSL_ZERO_PADDING=2
    • OPENSSL_NO_PADDING=3
  5. $iv 密初始化向量(可选)
  • 需要注意:如果$method为DES\-ECB,则$iv无需填写

二、解密用到的方法:

openssl_decrypt($data, $method, $password, $options, $iv)

参数说明:

  1. $data 要解密的数据
  2. 其他参数同加密方法

三、用法案例:

参数:

   $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方式

看字面意思,是用0填充,但是测试并不起作用

  • 加密

    $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"

结尾要去除填充字符0a
‘a’是为了兼容用OPENSSL_RAW_DATA加密的结果。

参照的文档有:

  • PHP 基础篇 - PHP 中 DES 加解密详解

    [https://www.jianshu.com/p/546...](https://www.jianshu.com/p/546137b8ac7a)
  • 关于mcrypt_encrypt和openssl_encrypt加密结果不一致的解决

    [http://www.heylc.com/fuanyuop...](http://www.heylc.com/fuanyuopenssl.html)
    

相关知识文章

  • RSA密码传输加密方案

    [https://wenku.baidu.com/view/...](https://wenku.baidu.com/view/83cb1d6df011f18583d049649b6648d7c1c7089d.html?re=view)
  • iOS 实现对称加密多种填充方式(ANSIX923、ISO10126、Zero)

    [https://www.jianshu.com/p/7b6...](https://www.jianshu.com/p/7b6f5aaa7680)
  • PHP由mcrypt扩展加密改为openssl扩展加密

    [https://www.xxling.com/blog/a...](https://www.xxling.com/blog/article/3114.aspx)
  • PHP用openssl_encrypt代替mcrypt_encrypt

    [https://coderlife.cn/1624.html](https://coderlife.cn/1624.html)
  • AES加密CBC模式兼容互通四种编程语言平台【PHP、Javascript、Java、C#】

    [https://my.oschina.net/Jacker...](https://my.oschina.net/Jacker/blog/86383)
  • 在PHP7.1中使用openssl取代mcrypt

    [https://swoole.app/2018/05/15...](https://swoole.app/2018/05/15/%E5%9C%A8php7-1%E4%B8%AD%E4%BD%BF%E7%94%A8openssl%E5%8F%96%E4%BB%A3mcrypt/)
  • PHP openssl加密扩展使用总结

    [https://www.bbsmax.com/A/ke5j...](https://www.bbsmax.com/A/ke5jNDe75r/)
  • PHP 7.2+使用openssl进行加解密

    [https://www.lytit.com/2018/01...](https://www.lytit.com/2018/01/26/118/)
  • PHP OpenSSL扩展 - 对称加密

    [https://www.jianshu.com/p/8f8...](https://www.jianshu.com/p/8f82e8fd123e)
  • DES 加解密工具

    [http://tool.chacuo.net/cryptdes](http://tool.chacuo.net/cryptdes)
  • RSA填充方式

    [https://www.jianshu.com/p/205...](https://www.jianshu.com/p/205abb4b9dc6)
  • AES加密模式和填充方式,hash,md5,ca

    [http://blog.sina.com.cn/s/blo...](http://blog.sina.com.cn/s/blog_679daa6b0100zmpp.html)
Responses