PHP DES加密解密

  最近公司在做接口对接,对方用的加密方式是DES加密,网上相关代码有很多很多,但是复制过来后总是解密后前面部分还是有乱码的存在,为此找了很多很多,终于知道问题所在,特此留下此文章,以防后续再出现此类情况。

DES概念

  DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。

DES算法入口参数

  DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

  DES的百度百科链接https://baike.baidu.com/item/DES/210508

PHP 加密解密方法

 1 /**
 2      *
 3      * 加密函数
 4      * 算法:des
 5      * 加密模式:cbc
 6      * 补齐方法:PKCS5
 7      *
 8      * @param unknown_type $input
 9      */
10     public function encrypt($str,$key,$vi="\0\0\0\0\0\0\0\0")
11     {
12         //加密,返回大写十六进制字符串
13         $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
14         //key长度8例如:1234abcd
15         $crypto = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');
16 
17         $str  = $this->pkcs5Pad($str, $size);
18         mcrypt_generic_init($crypto, $key, "\0\0\0\0\0\0\0\0");
19         $enc_question = mcrypt_generic($crypto, $str);
20         mcrypt_generic_deinit($crypto);
21         return strtoupper(bin2hex($enc_question));
22     }
23 
24     /**
25      * 解密函数
26      * 算法:des
27      * 加密模式:cbc
28      * 补齐方法:PKCS5
29      * @param unknown_type $input
30      */
31     public function decrypt($str,$key,$vi="\0\0\0\0\0\0\0\0")
32     {
33         $strBin = $this->hex2bin(strtolower($str));
34         //key长度8例如:1234abcd
35         $crypto = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');
36         mcrypt_generic_init($crypto, $key, $vi);
37         $str = mdecrypt_generic($crypto, $strBin);
38         mcrypt_generic_deinit($crypto);
39         $str = $this->pkcs5Unpad($str);
40         return $str;
41     }
42 
43     /*
44      * 把数据转成十六进制
45      */
46     public function hex2bin($hexData) {
47         $binData = "";
48         for ($i = 0; $i < strlen($hexData); $i += 2) {
49             $binData .= chr(hexdec(substr($hexData, $i, 2)));
50         }
51         return $binData;
52     }
53 
54     /**
55      * 填补需加密的字符串
56      * PKCS7Padding VS PKCS5Padding
57      * 区别,PKCS5Padding的blocksize为8字节,而PKCS7Padding的blocksize可以为1到255字节
58      * @param $text
59      * @param $blocksize
60      * @return string
61      */
62     public function pkcs5Pad($text, $blocksize) {
63         $pad = $blocksize - (strlen($text) % $blocksize);
64         return $text . str_repeat(chr($pad), $pad);
65     }
66 
67     /**
68      * 去除加密填补的字符串
69      * PKCS7Padding VS PKCS5Padding
70      * 区别,PKCS5Padding的blocksize为8字节,而PKCS7Padding的blocksize可以为1到255字节
71      * @param $text
72      * @return bool|string
73      */
74     public function pkcs5Unpad($text) {
75         $pad = ord($text{strlen($text) - 1});
76         if ($pad > strlen($text)) {
77             return false;
78         }
79         if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
80             return false;
81         }
82         return substr($text, 0, -1 * $pad);
83     }

以上是最终的加密解密代码

des在线解密解密地址:http://tool.chacuo.net/cryptdes

但是在写这段代码的过程中,对方给的偏移量是八个零,这个时候毫不疑问大家的$v='00000000',用这个偏移量的出来的结果是以下截图

为此,这个问题研究了两三天,但是一直没有头绪,最后度娘找到了一个

就是偏移量的写法问题

  $vi="\0\0\0\0\0\0\0\0"


以此为记

 

posted @ 2019-05-17 09:18  顾遥  阅读(325)  评论(0)    收藏  举报