Utils.php
4.68 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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php
namespace WebPlugin\Pay\Alimobilemini;
use WebPlugin\Pay\PayAbstract;
/**
* 支付宝手机极简支付工具类
* @author Smile
*
*/
class Utils extends PayAbstract
{
/**
* 构造函数
*/
public function __construct()
{
}
/**RSA签名
* $data待签名数据
* 签名用商户私钥,必须是没有经过pkcs8转换的私钥
* 最后的签名,需要用base64编码
* return Sign签名
*/
function sign($data)
{
//转换为openssl密钥,必须是没有经过pkcs8转换的私钥
$res = openssl_get_privatekey($this->priKey);
//调用openssl内置签名方法,生成签名$sign
openssl_sign($data, $sign, $res);
//释放资源
openssl_free_key($res);
//base64编码
$sign = base64_encode($sign);
return $sign;
}
/**
* RSA验签
* 验签用支付宝公钥
*
* return 验签是否通过 bool值
* @param array $data 待签名数据
* @param string $sign 需要验签的签名
* @return bool 验签是否通过 bool值
*/
function verify($data, $sign)
{
$pubKeyPath = dirname(__FILE__) . '/key/alipay_public_key.pem';
//转换为openssl格式密钥
$pubKey = file_get_contents($pubKeyPath);
$res = openssl_get_publickey($pubKey);
if ($res == false) {
while ($text = openssl_error_string())
echo "$text \n";
}
//调用openssl内置方法验签,返回bool值
$result = (bool)openssl_verify($data, base64_decode($sign), $res);
//释放资源
openssl_free_key($res);
//返回资源是否成功
return $result;
}
/**
* 获取返回时的签名验证结果
*
* @param $para_temp 通知返回来的参数数组
* @return string $sign 返回的签名结果
*/
function getSignVeryfy($para_temp)
{
//支付宝公钥路径
$pubKeyPath = dirname(__FILE__) . '/key/alipay_public_key.pem';
//签名类型:RSA
$sign_type = $para_temp['sign_type'];
//签名
$sign = $para_temp['sign'];
//除去待签名参数数组中的空值和签名参数
$para_filter = self::paraFilter($para_temp);
//对待签名参数数组排序
$para_sort = self::argSort($para_filter);
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = self::createLinkstring($para_sort);
switch (strtoupper($sign_type)) {
case "RSA" :
$isSgin = self::rsaVerify($prestr, $pubKeyPath, $sign);
break;
default :
$isSgin = false;
}
return $isSgin;
}
/**
* 除去数组中的空值和签名参数
* @param array $para 签名参数组
* @return array 去掉空值与签名参数后的新签名参数组
*/
function paraFilter($para)
{
$para_filter = array();
while (list ($key, $val) = each($para)) {
if ($key == "sign" || $key == "sign_type" || $val == "") {
continue;
} else {
$para_filter[$key] = $para[$key];
}
}
return $para_filter;
}
/**
* 对数组排序
* @param array $para 排序前的数组
* @return array 排序后的数组
*/
function argSort($para)
{
ksort($para);
reset($para);
return $para;
}
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param array $para 需要拼接的数组
* @return string 拼接完成以后的字符串
*/
function createLinkstring($para)
{
$arg = "";
while (list ($key, $val) = each($para)) {
$arg .= $key . "=" . $val . "&";
}
//去掉最后一个&字符
$arg = substr($arg, 0, count($arg) - 2);
//如果存在转义字符,那么去掉转义
if (get_magic_quotes_gpc()) {
$arg = stripslashes($arg);
}
return $arg;
}
/**
* RSA验签
* @param array $data 待签名数据
* @param string $ali_public_key_path 支付宝的公钥文件路径
* @param string $sign 要校对的的签名结果
* @return bool 验证结果
*/
function rsaVerify($data, $ali_public_key_path, $sign)
{
$pubKey = file_get_contents($ali_public_key_path);
$res = openssl_get_publickey($pubKey);
$result = (bool)openssl_verify($data, base64_decode($sign), $res);
openssl_free_key($res);
return $result;
}
}