forked from sbzhu/weworkapi_php
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpkcs7Encoder.php
More file actions
160 lines (148 loc) · 4.53 KB
/
Copy pathpkcs7Encoder.php
File metadata and controls
160 lines (148 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<?php
include_once "errorCode.php";
/**
* PKCS7Encoder class
*
* 提供基于PKCS7算法的加解密接口.
*/
class PKCS7Encoder
{
public static $block_size = 32;
/**
* 对需要加密的明文进行填充补位
* @param $text 需要进行填充补位操作的明文
* @return 补齐明文字符串
*/
function encode($text)
{
$block_size = PKCS7Encoder::$block_size;
$text_length = strlen($text);
//计算需要填充的位数
$amount_to_pad = PKCS7Encoder::$block_size - ($text_length % PKCS7Encoder::$block_size);
if ($amount_to_pad == 0) {
$amount_to_pad = PKCS7Encoder::block_size;
}
//获得补位所用的字符
$pad_chr = chr($amount_to_pad);
$tmp = "";
for ($index = 0; $index < $amount_to_pad; $index++) {
$tmp .= $pad_chr;
}
return $text . $tmp;
}
/**
* 对解密后的明文进行补位删除
* @param decrypted 解密后的明文
* @return 删除填充补位后的明文
*/
function decode($text)
{
$pad = ord(substr($text, -1));
if ($pad < 1 || $pad > PKCS7Encoder::$block_size) {
$pad = 0;
}
return substr($text, 0, (strlen($text) - $pad));
}
}
/**
* Prpcrypt class
*
* 提供接收和推送给公众平台消息的加解密接口.
*/
class Prpcrypt
{
public $key = null;
public $iv = null;
/**
* Prpcrypt constructor.
* @param $k
*/
public function __construct($k)
{
$this->key = base64_decode($k . '=');
$this->iv = substr($this->key, 0, 16);
}
/**
* 加密
*
* @param $text
* @param $receiveId
* @return array
*/
public function encrypt($text, $receiveId)
{
try {
//拼接
$text = $this->getRandomStr() . pack('N', strlen($text)) . $text . $receiveId;
//添加PKCS#7填充
$pkc_encoder = new PKCS7Encoder;
$text = $pkc_encoder->encode($text);
//加密
if (function_exists('openssl_encrypt')) {
$encrypted = openssl_encrypt($text, 'AES-256-CBC', $this->key, OPENSSL_ZERO_PADDING, $this->iv);
} else {
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, base64_decode($text), MCRYPT_MODE_CBC, $this->iv);
}
return array(ErrorCode::$OK, $encrypted);
} catch (Exception $e) {
print $e;
return array(MyErrorCode::$EncryptAESError, null);
}
}
/**
* 解密
*
* @param $encrypted
* @param $receiveId
* @return array
*/
public function decrypt($encrypted, $receiveId)
{
try {
//解密
if (function_exists('openssl_decrypt')) {
$decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $this->key, OPENSSL_ZERO_PADDING, $this->iv);
} else {
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key, base64_decode($encrypted), MCRYPT_MODE_CBC, $this->iv);
}
} catch (Exception $e) {
return array(ErrorCode::$DecryptAESError, null);
}
try {
//删除PKCS#7填充
$pkc_encoder = new PKCS7Encoder;
$result = $pkc_encoder->decode($decrypted);
if (strlen($result) < 16) {
return array();
}
//拆分
$content = substr($result, 16, strlen($result));
$len_list = unpack('N', substr($content, 0, 4));
$xml_len = $len_list[1];
$xml_content = substr($content, 4, $xml_len);
$from_receiveId = substr($content, $xml_len + 4);
} catch (Exception $e) {
print $e;
return array(ErrorCode::$IllegalBuffer, null);
}
if ($from_receiveId != $receiveId) {
return array(ErrorCode::$ValidateCorpidError, null);
}
return array(0, $xml_content);
}
/**
* 生成随机字符串
*
* @return string
*/
private function getRandomStr()
{
$str = '';
$str_pol = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyl';
$max = strlen($str_pol) - 1;
for ($i = 0; $i < 16; $i++) {
$str .= $str_pol[mt_rand(0, $max)];
}
return $str;
}
}