最近在对接客户的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)

参数说明:

  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无需填写

二、解密用到的方法:


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

参数说明:

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

三、用法案例:

参数:


  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) "�v���9z[���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加密的结果。 **

    参照的文档有:

    相关知识文章

    原文地址:https://segmentfault.com/a/1190000016804661

    php如何openssl_encrypt加密解密的更多相关文章

    1. PHP7.* AES的加密解密

      之前写过一篇: PHP AES的加密解密-----[弃用] 使用的是php5.*之前的mcrypt_decrypt 函数,该函数已经在php7.1后弃用了,上马的是openssl的openssl_en ...

    2. laravel cookie加密解密原理

      通过控制台的 cookie 信息我们会发现,每次请求之后,关键的 cookie,如PHPSESSID.XSRF-TOKEN 都会发生变化,并且都是很长的一串字符串. 其实这是一个 json 数组,其中 ...

    3. php中签名公钥、私钥(SHA1withRSA签名)以及AES(AES/ECB/PKCS5Padding)加密解密详解

      由于http请求是无状态,所以我们不知道请求方到底是谁.于是就诞生了签名,接收方和请求方协商一种签名方式进行验证,来取得互相信任,进行下一步业务逻辑交流. 其中签名用得很多的就是公钥私钥,用私钥签名, ...

    4. PHP实现sha1加密AES算法加密解密数据

      一.加密代码如下: /** * * @param string $string 需要加密的字符串 * @param string $key 密钥 * @return string */ public ...

    5. PHP7.2中AES加密解密方法mcrypt_module_open()替换方案 Function mcrypt_get_block_size() is deprecated

      直接粘代码,该类是基于微信公众号消息加密解密所提供的PHP DEMO改造而来,目前使用于彬彬大学APP接口token校验中. php的mcrypt 扩展已经过时了大约10年,并且用起来很复杂.因此它被 ...

    6. PHP的学习--RSA加密解密

      PHP服务端与客户端交互或者提供开放API时,通常需要对敏感的数据进行加密,这时候rsa非对称加密就能派上用处了. 举个通俗易懂的例子,假设我们再登录一个网站,发送账号和密码,请求被拦截了. 密码没加 ...

    7. 兼容javascript和C#的RSA加密解密算法,对web提交的数据进行加密传输

      Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都 ...

    8. .NET和JAVA中BYTE的区别以及JAVA中“DES/CBC/PKCS5PADDING” 加密解密在.NET中的实现

      场景:java 作为客户端调用已有的一个.net写的server的webservice,输入string,返回字节数组. 问题:返回的值不是自己想要的,跟.net客户端直接调用总是有差距 分析:平台不 ...

    9. php使用openssl进行Rsa长数据加密(117)解密(128) 和 DES 加密解密

      PHP使用openssl进行Rsa加密,如果要加密的明文太长则会出错,解决方法:加密的时候117个字符加密一次,然后把所有的密文拼接成一个密文:解密的时候需要128个字符解密一下,然后拼接成数据. 加 ...

    随机推荐

    1. layui(弹出层)

      首先引入文件 layui.css jquery.min.js layui.js 弹出层 data-method 后面的属性控制是什么弹窗,在js中写方法 <div class="sit ...

    2. (转载) Android开发时,那些相见恨晚的工具或网站!

      huangmindong的专栏       目录视图 摘要视图 订阅 赠书 | 异步2周年,技术图书免费选      程序员8月书讯      项目管理+代码托管+文档协作,开发更流畅 Android ...

    3. ActiveMQ学习笔记(22)----ActiveMQ的优化和使用建议

      1. 什么时候使用ActiveMQ 1. 异步通信 2. 一对多通信 3. 做个系统的集成,同构,异构 4. 作为RPC的替代 5. 多个应用相互解耦 6. 作为事件驱动架构的幕后支撑 7. 为了提高 ...

    4. JavaScript 中表达式和语句的区别

      1.语句和表达式 JavaScript中的表达式和语句是有区别的.一个表达式会产生一个值,它可以放在任何需要一个值的地方,比如,作为一个函数调用的参数.下面的每行代码都是一个表达式: myvar3 + ...

    5. idea运行提示Error:java:无效的源发行版:1.9

      如果你是jdk1.8 改到8即可,如图:

    6. C语言基础 (2) linux命令

      01.课程回顾 链接 ln 1.txt aaa.txt  硬链接 (两个相互独立 删除一个另外一个还在) ln -s 1.txt aaa.txt软连接 (后面的是快捷方式) 硬链接只能是文件,软连接可 ...

    7. Python2x,3x源码的区别,编译型解释型,变量,注释,if,用户交互input,基本数据类型3种

      cpu 内存 硬盘 操作系统 ​ cpu: 计算机的运算和计算中心,相当于人类的大脑. ​ 内存:暂时存储数据,临时加载数据应用程序,4G,8G,16G,32G #速度快,造价高,断电即消失 ​ 硬盘 ...

    8. [SCOI2016]美味(可持久化线段树)

      可持久化trie树?好像和可持久化权值线段树差不多.. 如果这题没有那个\(x[i]\)这题就是一个裸的可持久化trie树. 仔细想想,多了这个\(x[i]\)之后有什么影响? 就是我们查询区间的时候 ...

    9. [转载]深入Java单例模式

      在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下.   所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在 ...

    10. HTTP cookies 详解

      http://blog.csdn.net/lijing198997/article/details/9378047