资讯专栏INFORMATION COLUMN

php如何openssl_encrypt加密解密

JouyPub / 1523人阅读

摘要:密钥长度是位,超过位数密钥被忽略。跨语言做加密解密经常会出现问题,往往是填充方式不对编码不一致或者加密解密模式没有对应上造成。是为了兼容用加密的结果。

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

加密用到的方法:
 openssl_encrypt($data, $method, $password, $options, $iv)

参数说明:

$data 加密明文

$method 加密方法

DES-ECB

DES-CBC

DES-CTR

DES-OFB

DES-CFB

$passwd 加密密钥[密码]

$options 数据格式选项(可选)【选项有:】

0

OPENSSL_RAW_DATA=1

OPENSSL_ZERO_PADDING=2

OPENSSL_NO_PADDING=3

$iv 密初始化向量(可选)

需要注意:如果$method为DES-ECB,则$iv无需填写

二、解密用到的方法:
openssl_decrypt($data, $method, $password, $options, $iv)

参数说明:

$data 要解密的数据

其他参数同加密方法

三、用法案例:

参数:

   $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, "");
  }
  $result = openssl_encrypt($str_padded, $method, $passwd, OPENSSL_NO_PADDING);
  var_dump($result);
  echo "
"; 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, "");
  }
  $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加密的结果。 **

参照的文档有:

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

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

相关知识文章

RSA密码传输加密方案
https://wenku.baidu.com/view/...

iOS 实现对称加密多种填充方式(ANSIX923、ISO10126、Zero)
https://www.jianshu.com/p/7b6...

PHP由mcrypt扩展加密改为openssl扩展加密
https://www.xxling.com/blog/a...

PHP用openssl_encrypt代替mcrypt_encrypt
https://coderlife.cn/1624.html

AES加密CBC模式兼容互通四种编程语言平台【PHP、Javascript、Java、C#】
https://my.oschina.net/Jacker...

在PHP7.1中使用openssl取代mcrypt
https://swoole.app/2018/05/15...

PHP openssl加密扩展使用总结
https://www.bbsmax.com/A/ke5j...

PHP 7.2+使用openssl进行加解密
https://www.lytit.com/2018/01...

PHP OpenSSL扩展 - 对称加密
https://www.jianshu.com/p/8f8...

DES 加解密工具
http://tool.chacuo.net/cryptdes

RSA填充方式
https://www.jianshu.com/p/205...

AES加密模式和填充方式,hash,md5,ca
http://blog.sina.com.cn/s/blo...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29569.html

相关文章

  • php中使用openssl_encrypt代替mcrypt_encrypt实现js加密php解密的方

    摘要:项目背景因为自己开发的接口希望在传递的工程中可以保证参数是密文的形式,主要是前端使用加密,后端使用解密在网络上搜索了很多的方法,但是大部分的都是使用和进行端的加解密,但是众所周知的问题,这两个方法在以后将会被废弃,故而采用。 项目背景 因为自己开发的接口希望在传递的工程中可以保证参数是密文的形式,主要是前端使用js加密,后端使用php解密 在网络上搜索了很多的方法,但是大部分的都是使...

    wuyumin 评论0 收藏0
  • php中使用openssl_encrypt代替mcrypt_encrypt实现js加密php解密的方

    摘要:项目背景因为自己开发的接口希望在传递的工程中可以保证参数是密文的形式,主要是前端使用加密,后端使用解密在网络上搜索了很多的方法,但是大部分的都是使用和进行端的加解密,但是众所周知的问题,这两个方法在以后将会被废弃,故而采用。 项目背景 因为自己开发的接口希望在传递的工程中可以保证参数是密文的形式,主要是前端使用js加密,后端使用php解密 在网络上搜索了很多的方法,但是大部分的都是使...

    FullStackDeveloper 评论0 收藏0
  • PHP7.1废弃加密方法替换方案

    摘要:废弃加密方法替换方案前瞻最近,我负责在重构项目的支付渠道,因为之前都是接一个渠道在的方式,代码显的比较混乱,恰巧整体项目在微服务化,所以我们决定将支付做成一个微服务,独立出来。 PHP7.1废弃加密方法替换方案 前瞻 最近,我负责在重构项目的支付渠道,因为之前都是接一个渠道在ifelse的方式,代码显的比较混乱,恰巧整体项目在微服务化,所以我们决定将支付做成一个微服务,独立出来。当前比...

    afishhhhh 评论0 收藏0
  • Laravel 5.5 升级到 5.5.42 后遇到的 Cookie 序列化问题

    摘要:查阅官方文档后得知,新版为了防止对象的序列化反序列化漏洞被利用,不再对值进行自动的序列化和反序列化处理。举个栗子更新到后,因为不再自动对值进行序列化处理,而只能加密字符串数据,这个时候程序就会抛出错误。 最近手残升级了项目里 Laravel 的小版本号(v5.5.39 => v5.5.45),这不升级则已,一升级就出了问题! Sentry 平台上提示错误:openssl_encrypt...

    jollywing 评论0 收藏0
  • PHP的openssl加密扩展使用小结

    摘要:非对称加密与对称加密相对的是非对称加密,非对称加密的核心思想是使用一对相对的密匙,分为公匙和私匙,私匙自己安全保存,而将公匙公开。 引言 互联网的发展史上,安全性一直是开发者们相当重视的一个主题,为了实现数据传输安全,我们需要保证:数据来源(非伪造请求)、数据完整性(没有被人修改过)、数据私密性(密文,无法直接读取)等。虽然现在已经有SSL/TLS协议实现的HTTPS协议,但是因在客户...

    dockerclub 评论0 收藏0

发表评论

0条评论

JouyPub

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<