经常做银行的支付接口,私钥一般都是pfx格式(私钥用来加密生成签名发送报文),公钥是cer格式(公钥用来验证返回报文里的签名)。但是php里openssl只能用pem格式,每次转换都要用openssl命令在本地转好,很是麻烦。下面是直接php转换的代码。
私钥pfx转pem
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
|
//filePath为pfx文件路径
function
signfrompfx(
$strData
,
$filePath
,
$keyPass
)
{
if
(!
file_exists
(
$filePath
)) {
return
false;
}
$pkcs12
=
file_get_contents
(
$filePath
);
if
(openssl_pkcs12_read(
$pkcs12
,
$certs
,
$keyPass
)) {
$privateKey
=
$certs
[
'pkey'
];
$publicKey
=
$certs
[
'cert'
];
$signedMsg
=
""
;
if
(openssl_sign(
$strData
,
$signedMsg
,
$privateKey
)) {
$signedMsg
=bin2hex(
$signedMsg
);
//这个看情况。有些不需要转换成16进制,有些需要base64编码。看各个接口
return
$signedMsg
;
}
else
{
return
''
;
}
}
else
{
return
'0'
;
}
}
|
公钥cer转pem(即x.509证书dem格式转换为pem)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
function
verifyReturn(
$data
,
$signature
,
$filePath
){
/*<br>filePath为crt,cert文件路径。x.509证书
cer to dem, Convert .cer to .pem, cURL uses .pem
*/
$certificateCAcerContent
=
file_get_contents
(
$filePath
);
$certificateCApemContent
=
'-----BEGIN CERTIFICATE-----'
.PHP_EOL
.
chunk_split
(
base64_encode
(
$certificateCAcerContent
), 64, PHP_EOL)
.
'-----END CERTIFICATE-----'
.PHP_EOL;*/
$pubkeyid
= openssl_get_publickey(
$certificateCApemContent
);
$len
=
strlen
(
$signature
);
$signature
= pack(
"H"
.
$len
,
$signature
);
//Php-16进制转换为2进制,看情况。有些接口不需要,有些需要base64解码
$data
=
str_replace
(
'<?xml version=\"1.0\" encoding=\"GBK\"?>'
,
'<?xml version="1.0" encoding="GBK"?>'
,
$data
);
//这个看情况。
// state whether signature is okay or not
$ok
= openssl_verify(
$data
,
$signature
,
$pubkeyid
);
openssl_free_key(
$pubkeyid
);
return
$ok
;
}
|
文章来源:http://www.cnblogs.com/showker/p/3603202.html