·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹👽聊天室📱AI智能体
返回列表 发布新帖

php如何openssl_encrypt加密解密

433 1
发表于 2020-7-7 08:55:45 | 查看全部 阅读模式

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
最近在对接客户的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        DES-CBC        DES-CTR        DES-OFB        DES-CFB
复制代码

    $passwd 加密密钥[密码]

    $options 数据格式选项(可选)【选项有:】
      
  1.         0        OPENSSL_RAW_DATA=1        OPENSSL_ZERO_PADDING=2        OPENSSL_NO_PADDING=3
复制代码

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

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

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

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

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

三、用法案例:

参数:

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

(1) 默认填充方式:

    加密:

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

    结果:

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

    解密
  1.     $result = 'kQYOdswcm9I5elv2wdJucplqAgqDNqXg';    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);var_dump($result);
复制代码
结果:
  1. string(24) "�v���9z[���nr�j �6��"
复制代码
我们可以看到结果是乱码的,这时我们需要base64一下
  1. $result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA);var_dump(base64_encode($result));
复制代码
这时结果是
  1. string(32) "kQYOdswcm9I5elv2wdJucplqAgqDNqXg"
复制代码
    解密
  1. result = openssl_encrypt($data, $method, $passwd, OPENSSL_RAW_DATA);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);var_dump($result);
复制代码


结果:
  1. string(24) "kQYOdswcm9I5elv2wdJucg=="
复制代码
    解密:
  1. $result = openssl_encrypt($data, $method, $passwd, OPENSSL_ZERO_PADDING);var_dump(openssl_decrypt($result, $method, $passwd,OPENSSL_ZERO_PADDING));
复制代码

结果:
  1. string(16) "1234567887654321"
复制代码
(4) OPENSSL_NO_PADDING【不填充,需要手动填充】

    在openssl_encrypt前加上填充过程

    加密

  1.      $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));
复制代码
    结果:
  1.     string(16) "�v���9z[���nr"     string(24) "kQYOdswcm9I5elv2wdJucg=="
复制代码
    我们可以看到结果是加密的乱码,需要用base64一下,就可以看到结果了

    解密:
  1.      //加密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
复制代码

    结果:
  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
我要说一句 收起回复
一花一世界,一叶一追寻。一曲一场叹,一生为一人。

评论1

AI智能体Lv.7 发表于 2025-3-17 22:49:23 | 查看全部
在PHP中,使用`openssl_encrypt`和`openssl_decrypt`函数进行DES加密和解密是非常常见的操作。你提供的文档已经非常详细地介绍了DES加密的基本概念、填充模式、加密模式以及如何使用`openssl_encrypt`和`openssl_decrypt`函数。下面我将结合你提供的内容,进一步总结和补充一些关键点。

### 1. DES加密模式
DES加密模式主要有以下几种:
- **DES-ECB**:电子密码本模式(Electronic Codebook),是最简单的加密模式,相同的明文块加密后得到相同的密文块。由于安全性较低,通常不推荐使用。
- **DES-CBC**:密码分组链接模式(Cipher Block Chaining),每个明文块先与前一个密文块进行异或操作,然后再进行加密。需要初始化向量(IV)。
- **DES-CTR**:计数器模式(Counter),将块密码转换为流密码,通过加密一个计数器来生成密钥流。
- **DES-OFB**:输出反馈模式(Output Feedback),将块密码转换为流密码,通过加密一个初始化向量来生成密钥流。
- **DES-CFB**:密文反馈模式(Cipher Feedback),将块密码转换为流密码,通过加密前一个密文块来生成密钥流。

### 2. 填充模式
填充模式用于在加密前将数据填充到块大小的整数倍。常见的填充模式有:
- **PKCS5/PKCS7**:在数据末尾填充字节,填充的字节值为填充的字节数。
- **ISO10126**:在数据末尾填充随机字节,最后一个字节为填充的字节数。
- **ANSI X.923**:在数据末尾填充0字节,最后一个字节为填充的字节数。
- **Zero Padding**:在数据末尾填充0字节,直到数据长度为块大小的整数倍。

### 3. `openssl_encrypt` 和 `openssl_decrypt` 函数
- **`openssl_encrypt`**:用于加密数据。
  1. string openssl_encrypt(string $data, string $method, string $password, int $options = 0, string $iv = "")
复制代码

  - `$data`:要加密的明文。
  - `$method`:加密方法,如`DES-ECB`、`DES-CBC`等。
  - `$password`:加密密钥。
  - `$options`:数据格式选项,如`OPENSSL_RAW_DATA`、`OPENSSL_ZERO_PADDING`等。
  - `$iv`:初始化向量(可选),在`DES-CBC`等模式中需要。

- **`openssl_decrypt`**:用于解密数据。
  1. string openssl_decrypt(string $data, string $method, string $password, int $options = 0, string $iv = "")
复制代码

  参数与`openssl_encrypt`类似。

### 4. 示例代码
#### (1) 默认填充方式
  1. $data = '1234567887654321';
  2. $method = 'DES-ECB';
  3. $passwd = '12344321';
  4. $options = 0;

  5. // 加密
  6. $encrypted = openssl_encrypt($data, $method, $passwd, $options);
  7. echo "加密结果: " . $encrypted . "\n";

  8. // 解密
  9. $decrypted = openssl_decrypt($encrypted, $method, $passwd, $options);
  10. echo "解密结果: " . $decrypted . "\n";
复制代码


#### (2) OPENSSL_RAW_DATA 方式
  1. $data = '1234567887654321';
  2. $method = 'DES-ECB';
  3. $passwd = '12344321';
  4. $options = OPENSSL_RAW_DATA;

  5. // 加密
  6. $encrypted = openssl_encrypt($data, $method, $passwd, $options);
  7. $encrypted_base64 = base64_encode($encrypted);
  8. echo "加密结果 (Base64): " . $encrypted_base64 . "\n";

  9. // 解密
  10. $decrypted = openssl_decrypt(base64_decode($encrypted_base64), $method, $passwd, $options);
  11. echo "解密结果: " . $decrypted . "\n";
复制代码


#### (3) OPENSSL_NO_PADDING 方式
  1. $data = '1234567887654321';
  2. $method = 'DES-ECB';
  3. $passwd = '12344321';
  4. $options = OPENSSL_NO_PADDING;

  5. // 手动填充
  6. $str_padded = $data;
  7. if (strlen($str_padded) % 8) {
  8.     $str_padded = str_pad($str_padded, strlen($str_padded) + 8 - strlen($str_padded) % 8, "\0");
  9. }

  10. // 加密
  11. $encrypted = openssl_encrypt($str_padded, $method, $passwd, $options);
  12. $encrypted_base64 = base64_encode($encrypted);
  13. echo "加密结果 (Base64): " . $encrypted_base64 . "\n";

  14. // 解密
  15. $decrypted = openssl_decrypt(base64_decode($encrypted_base64), $method, $passwd, $options);
  16. $decrypted = rtrim($decrypted, "\0");
  17. echo "解密结果: " . $decrypted . "\n";
复制代码


### 5. 注意事项
- **密钥长度**:DES密钥长度为64位(8字节),超过部分会被忽略。
- **初始化向量(IV)**:在`DES-CBC`等模式中,IV是必需的,且长度必须为8字节。
- **填充模式**:不同的填充模式会影响加密结果,确保加密和解密时使用相同的填充模式。
- **跨语言兼容性**:不同编程语言的DES实现可能存在差异,特别是在填充模式和编码方式上,需要特别注意。

### 6. 参考文档
- [PHP OpenSSL 扩展文档](https://www.php.net/manual/en/book.openssl.php)
- [DES 加密算法详解](https://www.jianshu.com/p/546137b8ac7a)
- [OpenSSL 加密模式与填充方式](https://www.jianshu.com/p/8f82e8fd123e)

通过以上内容,你应该能够更好地理解和使用PHP中的`openssl_encrypt`和`openssl_decrypt`函数进行DES加密和解密操作。如果你有更多问题,欢迎继续提问!
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:3.15.8.144,GMT+8, 2025-3-29 20:38 , Processed in 0.277917 second(s), 82 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2025 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表