最近在使用PHP对接许多供应商的接口,各种各样的语言各种格式要求的接口都有,涉及到数据的 MD5加密,sha1 加密,sha256加密、解密、签名验证等各种问题。对于开发者来说需要深入理解HTTP协议的各个数据参数的含义。
网络协议
1、请求使用http协议,GET请求方式。注:请求如果涉及中文或者特殊字符,请做utf-8 进行urlencode编码。
2、返回格式为默认为xml,如果http请求返回500错误,务必在请求头Accept加上application/xml;
如需返回json格式,请把http 请求头中的Accept 改为 application/json;charset=UTF-8。
**Content-Type:**text/plain;
**Content-Type:**application/json; charset=utf-8;
**Content-Type:**application/x-www-form-urlencoded;
php rsa2解密,PHP RSA2 加密 、 解密 、签名 、验证签名
-------------------------------------------------------------------------------------------------------
RSA2 标准算法名称 SHA256WithRSA
1、RSA非对称加密技术
2、SHA256 是SHA-2下细分出的一种算法
SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准,由美国国家安全局研发,属于SHA算法之一,是SHA-1的后继者。
详细介绍连接:https://blog.youkuaiyun.com/u011583927/article/details/80905740
1、加密和解密
公钥是公开的密钥,有加密方使用。只用于加密无法解密。私钥是不公开的,别人无法获取,用户解密。
注意的是,为什么私钥对同一数据进行签名加密的结果是一样的,使用公钥进行加密就不一样了呢?
详细请参考:https://blog.youkuaiyun.com/guyongqiangx/article/details/74930951
2、签名和验证签名
签名是由发送数据的一方发起的,防止传输过程中被篡改数据内容。因此签名使用的是私钥。而验证签名使用的是公钥。
附带:
java RSA2 加密、解密 、签名和验证签名 https://blog.youkuaiyun.com/TaLinBoy/article/details/106124535
IOS:RSA2 加密、解密 、签名和验证签名 https://blog.youkuaiyun.com/TaLinBoy/article/details/106140526
/** POST原始数据请求(Json) */
function sendPostRaw(
u
r
l
,
url,
url,dataString,$headers=[]){
c
u
r
l
=
c
u
r
l
_
i
n
i
t
(
)
;
c
u
r
l
_
s
e
t
o
p
t
_
a
r
r
a
y
(
curl = curl\_init(); curl\_setopt\_array(
curl=curl_init();curl_setopt_array(curl, array(
CURLOPT_URL =>
u
r
l
,
C
U
R
L
O
P
T
_
R
E
T
U
R
N
T
R
A
N
S
F
E
R
=
>
t
r
u
e
,
C
U
R
L
O
P
T
_
S
S
L
_
V
E
R
I
F
Y
P
E
E
R
=
>
f
a
l
s
e
,
C
U
R
L
O
P
T
_
S
S
L
_
V
E
R
I
F
Y
H
O
S
T
=
>
f
a
l
s
e
,
C
U
R
L
O
P
T
_
E
N
C
O
D
I
N
G
=
>
′
′
,
C
U
R
L
O
P
T
_
M
A
X
R
E
D
I
R
S
=
>
10
,
C
U
R
L
O
P
T
_
T
I
M
E
O
U
T
=
>
0
,
C
U
R
L
O
P
T
_
F
O
L
L
O
W
L
O
C
A
T
I
O
N
=
>
t
r
u
e
,
C
U
R
L
O
P
T
_
H
T
T
P
_
V
E
R
S
I
O
N
=
>
C
U
R
L
_
H
T
T
P
_
V
E
R
S
I
O
N
_
1
_
1
,
C
U
R
L
O
P
T
_
C
U
S
T
O
M
R
E
Q
U
E
S
T
=
>
′
P
O
S
T
′
,
C
U
R
L
O
P
T
_
P
O
S
T
F
I
E
L
D
S
=
>
url, CURLOPT\_RETURNTRANSFER => true, CURLOPT\_SSL\_VERIFYPEER => false, CURLOPT\_SSL\_VERIFYHOST => false, CURLOPT\_ENCODING => '', CURLOPT\_MAXREDIRS => 10, CURLOPT\_TIMEOUT => 0, CURLOPT\_FOLLOWLOCATION => true, CURLOPT\_HTTP\_VERSION => CURL\_HTTP\_VERSION\_1\_1, CURLOPT\_CUSTOMREQUEST => 'POST', CURLOPT\_POSTFIELDS =>
url,CURLOPT_RETURNTRANSFER=>true,CURLOPT_SSL_VERIFYPEER=>false,CURLOPT_SSL_VERIFYHOST=>false,CURLOPT_ENCODING=>′′,CURLOPT_MAXREDIRS=>10,CURLOPT_TIMEOUT=>0,CURLOPT_FOLLOWLOCATION=>true,CURLOPT_HTTP_VERSION=>CURL_HTTP_VERSION_1_1,CURLOPT_CUSTOMREQUEST=>′POST′,CURLOPT_POSTFIELDS=>dataString,
CURLOPT_HTTPHEADER => array(
‘Content-Type: application/json; charset=utf-8’, //Content-Type: text/plain
'Content-Length: '.strlen(
d
a
t
a
S
t
r
i
n
g
)
,
′
b
u
s
i
n
e
s
s
I
d
:
′
.
dataString), 'businessId: '.
dataString),′businessId:′.headers[‘businessId’],
'nonce: '.KaTeX parse error: Undefined control sequence: \[ at position 8: headers\̲[̲'nonce'\], 't…headers[‘timestamp’],
'signType: '.KaTeX parse error: Undefined control sequence: \[ at position 8: headers\̲[̲'signType'\], …headers[‘sign’],
),
));
r
e
s
p
o
n
s
e
=
c
u
r
l
_
e
x
e
c
(
response = curl\_exec(
response=curl_exec(curl);
curl_close($curl);
return $response;
}
/**post提交数据
* @param string $url 请求Url
* @param array KaTeX parse error: Undefined control sequence: \* at position 15: datas 提交的数据 \̲*̲ @return String…url,
p
a
r
a
m
s
,
params,
params,isPost = 1,
h
t
t
p
s
=
0
,
https = 0,
https=0,isJson = 0)
{
$httpInfo = array();
c
h
=
c
u
r
l
_
i
n
i
t
(
)
;
c
u
r
l
_
s
e
t
o
p
t
(
ch = curl\_init(); curl\_setopt(
ch=curl_init();curl_setopt(ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt(
c
h
,
C
U
R
L
O
P
T
_
U
S
E
R
A
G
E
N
T
,
′
M
o
z
i
l
l
a
/
5.0
(
W
i
n
d
o
w
s
N
T
10.0
;
W
O
W
64
)
A
p
p
l
e
W
e
b
K
i
t
/
537.36
(
K
H
T
M
L
,
l
i
k
e
G
e
c
k
o
)
C
h
r
o
m
e
/
41.0.2272.118
S
a
f
a
r
i
/
537.3
6
′
)
;
c
u
r
l
_
s
e
t
o
p
t
(
ch, CURLOPT\_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'); curl\_setopt(
ch,CURLOPT_USERAGENT,′Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/41.0.2272.118Safari/537.36′);curl_setopt(ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt(
c
h
,
C
U
R
L
O
P
T
_
T
I
M
E
O
U
T
,
30
)
;
c
u
r
l
_
s
e
t
o
p
t
(
ch, CURLOPT\_TIMEOUT, 30); curl\_setopt(
ch,CURLOPT_TIMEOUT,30);curl_setopt(ch, CURLOPT_RETURNTRANSFER, true);
if (KaTeX parse error: Expected '}', got 'EOF' at end of input: … curl\_setopt(ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt(KaTeX parse error: Expected 'EOF', got '}' at position 62: …查SSL加密算法是否存在 }̲ if (isPost) {
curl_setopt(
c
h
,
C
U
R
L
O
P
T
_
P
O
S
T
,
t
r
u
e
)
;
c
u
r
l
_
s
e
t
o
p
t
(
ch, CURLOPT\_POST, true); curl\_setopt(
ch,CURLOPT_POST,true);curl_setopt(ch, CURLOPT_POSTFIELDS,
p
a
r
a
m
s
)
;
c
u
r
l
_
s
e
t
o
p
t
(
params); curl\_setopt(
params);curl_setopt(ch, CURLOPT_URL, KaTeX parse error: Expected 'EOF', got '}' at position 9: url); }̲ else { if (params) {
if (is_array($params)) {
p
a
r
a
m
s
=
h
t
t
p
_
b
u
i
l
d
_
q
u
e
r
y
(
params = http\_build\_query(
params=http_build_query(params);
}
curl_setopt($ch, CURLOPT_URL, $url . ‘’ . KaTeX parse error: Expected 'EOF', got '}' at position 12: params); }̲ else { curl\…ch, CURLOPT_URL, KaTeX parse error: Expected 'EOF', got '}' at position 9: url); }̲ } if (isJson) {
curl_setopt(
c
h
,
C
U
R
L
O
P
T
_
H
E
A
D
E
R
,
0
)
;
c
u
r
l
_
s
e
t
o
p
t
(
ch, CURLOPT\_HEADER, 0); curl\_setopt(
ch,CURLOPT_HEADER,0);curl_setopt(ch, CURLOPT_HTTPHEADER, array(
‘Content-Type: application/x-www-form-urlencoded; charset=utf-8’,
“Accept: application/x-www-form-urlencoded”,
‘Cache-Control: no-cache’,
‘Pragma: no-cache’
));
}
r
e
s
p
o
n
s
e
=
c
u
r
l
_
e
x
e
c
(
response = curl\_exec(
response=curl_exec(ch);
if ($response === false) {
return false;
}
h
t
t
p
C
o
d
e
=
c
u
r
l
_
g
e
t
i
n
f
o
(
httpCode = curl\_getinfo(
httpCode=curl_getinfo(ch, CURLINFO_HTTP_CODE);
h
t
t
p
I
n
f
o
=
a
r
r
a
y
_
m
e
r
g
e
(
httpInfo = array\_merge(
httpInfo=array_merge(httpInfo, curl_getinfo(
c
h
)
)
;
c
u
r
l
_
c
l
o
s
e
(
ch)); curl\_close(
ch));curl_close(ch);
return $response;
}
/** RSA签名(空字符串参与签名)
*
p
o
s
t
=
a
r
r
a
y
_
f
i
l
t
e
r
(
post = array\_filter(
post=array_filter(post); //参数值为空的,不参与签名
*/
private function rsaSign(KaTeX parse error: Expected '}', got 'EOF' at end of input: …-升序)排序 ksort(params);
//2.拼接成字符串string
s
t
r
i
n
g
=
′
′
;
f
o
r
e
a
c
h
(
string = ''; foreach (
string=′′;foreach(params as $key => $v) {
s
t
r
i
n
g
.
=
(
s
t
r
i
n
g
)
(
string .= (string)(
string.=(string)(key . ‘=’ . $v . ‘&’);
}
//3.拼接得到signTemp字符串
$signTemp = $string . ‘MerchantKey=’ . $this->key;
//4.获取RSA私钥信息
a
b
s
P
a
t
h
=
d
i
r
n
a
m
e
(
_
_
F
I
L
E
_
_
)
.
′
.
/
.
.
/
.
.
/
c
o
n
f
i
g
/
s
s
l
/
r
e
n
y
u
e
_
r
s
a
_
p
r
i
v
a
t
e
_
k
e
y
.
p
e
m
′
;
/
/
(
正式私钥
)
i
f
(
absPath = dirname(\_\_FILE\_\_) . './../../config/ssl/renyue\_rsa\_private\_key.pem'; //(正式私钥) if(
absPath=dirname(__FILE__).′./../../config/ssl/renyue_rsa_private_key.pem′;//(正式私钥)if(this->environment==‘test’){
$absPath = dirname(__FILE__) . ‘./…/…/config/ssl/renyue_rsa_private_key_test.pem’; //(测试私钥)
}
c
o
n
t
e
n
t
=
f
i
l
e
_
g
e
t
_
c
o
n
t
e
n
t
s
(
content = file\_get\_contents(
content=file_get_contents(absPath);
s
C
o
n
t
e
n
t
=
o
p
e
n
s
s
l
_
p
k
e
y
_
g
e
t
_
p
r
i
v
a
t
e
(
sContent = openssl\_pkey\_get\_private(
sContent=openssl_pkey_get_private(content);
//5.PHP-SHA256WithRSA 签名算法加密
openssl_sign($signTemp, $signature,
s
C
o
n
t
e
n
t
,
"
S
H
A
256
"
)
;
/
/
6.
b
a
s
e
64
转换,得到
S
i
g
n
S
e
c
r
e
t
值
r
e
t
u
r
n
b
a
s
e
64
_
e
n
c
o
d
e
(
sContent, "SHA256"); //6.base64转换,得到SignSecret值 return base64\_encode(
sContent,"SHA256");//6.base64转换,得到SignSecret值returnbase64_encode(signature);
}
/**接口回执解密
* KaTeX parse error: Undefined control sequence: \* at position 398: …SJUw%3D%3D"; \̲*̲ 解密成功示例:string(…returnSign=‘’)
{
//1.获取签名回执
//
r
e
t
u
r
n
S
i
g
n
=
u
r
l
d
e
c
o
d
e
(
returnSign = urldecode(
returnSign=urldecode(returnSign);
//2.获取RSA私钥信息
a
b
s
P
a
t
h
=
d
i
r
n
a
m
e
(
_
_
F
I
L
E
_
_
)
.
′
/
.
/
.
.
/
.
.
/
c
o
n
f
i
g
/
s
s
l
/
r
e
n
y
u
e
_
r
s
a
_
p
r
i
v
a
t
e
_
k
e
y
.
p
e
m
′
;
/
/
(
正式私钥
)
i
f
(
absPath = dirname(\_\_FILE\_\_) . '/./../../config/ssl/renyue\_rsa\_private\_key.pem'; //(正式私钥) if(
absPath=dirname(__FILE__).′/./../../config/ssl/renyue_rsa_private_key.pem′;//(正式私钥)if(this->environment==‘test’){
$absPath = dirname(__FILE__) . ‘/./…/…/config/ssl/renyue_rsa_private_key_test.pem’; //(测试私钥)
}
c
o
n
t
e
n
t
=
f
i
l
e
_
g
e
t
_
c
o
n
t
e
n
t
s
(
content = file\_get\_contents(
content=file_get_contents(absPath);
s
C
o
n
t
e
n
t
=
o
p
e
n
s
s
l
_
p
k
e
y
_
g
e
t
_
p
r
i
v
a
t
e
(
sContent = openssl\_pkey\_get\_private(
sContent=openssl_pkey_get_private(content);
//3.解密数据信息
openssl_private_decrypt(base64_decode($returnSign), $decrypted, $sContent);
//4.返回解密数据
return $decrypted;
}
sha1 加密(长度40字节)
--------------------------------------------------------------
$str = ‘203fpid’;
s h a 1 = s h a 1 ( sha1 = sha1( sha1=sha1(str);
echo $sha1.‘
’;
php sha256加密 (长度64)
--------------------------------------------------------------
$str = ‘203fpidf02lvj!!_@#_!’;
s h a 256 = h a s h ( ′ s h a 25 6 ′ , sha256 = hash('sha256', sha256=hash(′sha256′,str);
echo $sha256.‘
’;
/** 生成签名(哈希sha256 64位)
* @param KaTeX parse error: Undefined control sequence: \* at position 8: data \̲*̲ @return false|…data){
d
a
t
a
=
a
r
r
a
y
_
f
i
l
t
e
r
(
data = array\_filter(
data=array_filter(data);
ksort($data);
KaTeX parse error: Undefined control sequence: \[ at position 9: temps = \̲[̲\]; foreach (data as $key => $value) {
$temps[] = sprintf(‘%s=%s’, $key, $value);
}
$signBefore = $this->app_secret.implode(‘&’,
t
e
m
p
s
)
;
r
e
t
u
r
n
h
a
s
h
(
′
s
h
a
25
6
′
,
temps); return hash('sha256',
temps);returnhash(′sha256′,signBefore);
}