i漂泊

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 608|回复: 0

php如何openssl_encrypt加密解密

[复制链接]
TA的礼物信息
  • 收到:0
  • 送出:2
发表于 2020-6-18 11:24:08 | 显示全部楼层 |阅读模式
最近在对接客户的CRM系统,获取令牌时,要用DES方式加密解密,由于之前没有搞错这种加密方式,经过请教了“百度”和“谷歌”两个老师后,结合了多篇文档内容后,终于实现了。
一、DES介绍

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

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

加密用到的方法:
  1. 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 密初始化向量(可选)

    需要注意:如果method为DES−ECB,则

    method为DES−ECB,则iv无需填写

二、解密用到的方法:
  1. openssl_decrypt($data, $method, $password, $options, $iv)
复制代码
参数说明:

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

三、用法案例:

参数:

   
  1.    $data = '1234567887654321';//加密明文
  2.    $method = 'DES-ECB';//加密方法
  3.    $passwd = '12344321';//加密密钥
  4.    $options = 0;//数据格式选项(可选)
  5.    $iv = '';//加密初始化向量(可选)
复制代码


(1) 默认填充方式:

    加密:

   
  1. $result = openssl_encrypt($data, $method, $passwd, $options);
  2. var_dump($result);
复制代码


    结果:

   
  1. string(32) "kQYOdswcm9I5elv2wdJucplqAgqDNqXg"
复制代码


    解密

  1.     $result = 'kQYOdswcm9I5elv2wdJucplqAgqDNqXg';
  2.     var_dump(openssl_decrypt($result, $method, $passwd, 0));
复制代码

    结果:

  1.     string(16) "1234567887654321"
复制代码


(2) OPENSSL_RAW_DATA方式【会用PKCS#7进行补位】

    加密

  1. $result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA);
  2. var_dump($result);
复制代码

结果:
  1. string(24) "�v���9z[���nr�j �6��"
复制代码

我们可以看到结果是乱码的,这时我们需要base64一下

  1. $result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA);
  2. var_dump(base64_encode($result));
复制代码

这时结果是

  1. string(32) "kQYOdswcm9I5elv2wdJucplqAgqDNqXg"
复制代码
    解密

  1. result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA);

  2. var_dump(openssl_decrypt($result, $method, $passwd,OPENSSL_RAW_DATA));
复制代码


结果:

  1. string(16) "1234567887654321"
复制代码



我们可以看到:默认填充方式与OPENSSL_RAW_DATA,这两种方式加密结果是一样的
(3) OPENSSL_ZERO_PADDING方式

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

    加密

  1. $result = openssl_encrypt($data, $method, $passwd, OPENSSL_ZERO_PADDING);
  2. var_dump($result);
复制代码



结果:

  1. string(24) "kQYOdswcm9I5elv2wdJucg=="
复制代码

    解密:

  1. $result = openssl_encrypt($data, $method, $passwd, OPENSSL_ZERO_PADDING);
  2. var_dump(openssl_decrypt($result, $method, $passwd,OPENSSL_ZERO_PADDING));
复制代码


结果:

  1. string(16) "1234567887654321"
复制代码

(4) OPENSSL_NO_PADDING【不填充,需要手动填充】

    在openssl_encrypt前加上填充过程

    加密


  1.      $str_padded = $data;
  2.       if (strlen($str_padded) % 16) {
  3.           $str_padded = str_pad($str_padded,strlen($str_padded) + 16 - strlen($str_padded) % 16, "\0");
  4.       }
  5.       $result = openssl_encrypt($str_padded, $method, $passwd, OPENSSL_NO_PADDING);
  6.       var_dump($result);
  7.       echo '<br>';
  8.       var_dump( base64_encode($result));
复制代码

    结果:

  1.     string(16) "&#65533;v&#65533;&#65533;&#65533;9z[&#65533;&#65533;&#65533;nr"
  2.     string(24) "kQYOdswcm9I5elv2wdJucg=="
复制代码

    我们可以看到结果是加密的乱码,需要用base64一下,就可以看到结果了

    解密:

  1.      //加密begin
  2.       $str_padded = $data;
  3.       if (strlen($str_padded) % 16) {
  4.           $str_padded = str_pad($str_padded,strlen($str_padded) + 16 - strlen($str_padded) % 16, "\0");
  5.       }
  6.       $result = openssl_encrypt($str_padded, $method, $passwd, OPENSSL_NO_PADDING);
  7.       //加密end
  8.      //解密begin
  9.      $str = base64_encode($result);
  10.      $m = openssl_decrypt( base64_decode($str) , $method, $passwd, OPENSSL_NO_PADDING);
  11.      var_dump( rtrim( rtrim( $m,chr(0) ), chr(7) ) );
  12.      //解密 end
复制代码


    结果:

  1.     string(16) "1234567887654321"
复制代码


** 结尾要去除填充字符’\0’和’\a’。
‘\a’是为了兼容用OPENSSL_RAW_DATA加密的结果。 **
参照的文档有:

    PHP 基础篇 - PHP 中 DES 加解密详解
    https://www.jianshu.com/p/546137b8ac7a

    关于mcrypt_encrypt和openssl_encrypt加密结果不一致的解决
    http://www.heylc.com/fuanyuopenssl.html

相关知识文章

    RSA密码传输加密方案
    https://wenku.baidu.com/view/83c ... c7089d.html?re=view
    iOS 实现对称加密多种填充方式(ANSIX923、ISO10126、Zero)
    https://www.jianshu.com/p/7b6f5aaa7680
    PHP由mcrypt扩展加密改为openssl扩展加密
    https://www.xxling.com/blog/article/3114.aspx
    PHP用openssl_encrypt代替mcrypt_encrypt
    https://coderlife.cn/1624.html
    AES加密CBC模式兼容互通四种编程语言平台【PHP、Javascript、Java、C#】
    https://my.oschina.net/Jacker/blog/86383
    在PHP7.1中使用openssl取代mcrypt
    https://swoole.app/2018/05/15/在php7-1中使用openssl取代mcrypt/
    PHP openssl加密扩展使用总结
    https://www.bbsmax.com/A/ke5jNDe75r/
    PHP 7.2+使用openssl进行加解密
    https://www.lytit.com/2018/01/26/118/
    PHP OpenSSL扩展 - 对称加密
    https://www.jianshu.com/p/8f82e8fd123e
    DES 加解密工具
    http://tool.chacuo.net/cryptdes
    RSA填充方式
    https://www.jianshu.com/p/205abb4b9dc6
    AES加密模式和填充方式,hash,md5,ca
    http://blog.sina.com.cn/s/blog_679daa6b0100zmpp.html



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|IPiaoBo Inc. ( 渝ICP备17002826号 )

GMT+8, 2024-3-28 22:46 , Processed in 0.069732 second(s), 43 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表