今天公司遇到一个支付项目 对方给过来的接口使用的是RSA验证 给到了一个.pfx的证书,顿时懵逼 马上问Google PHP RSA怎么玩的,结果网上都是一堆复制粘贴的东西 毫无营养。都说要什么转成.pem的文件形式才行,害得我搞了半天终于可以实现加密了,但是问题出现了,加密出来的字符串和接口提供方给过来的加密字符串示例不一样,明显是不通的。自己又是翻PHP帮助文档,又是瞎折腾 终于搞定了 很多支付类 银行接口都要用这种形式的验证 ,不多说 代码如下
<?php
/**
* 生成签名前的字符串
*
* @param $params
* @return string
*/
function getParamsString($params)
{
if (!is_array($params))
$params = array();
ksort($params);
$str = '';
foreach ($params as $k => $v) {
$str .= $v != ''?$k . $v:'';
}
return $str;
}
/**
* 根据原文生成签名内容
*
* @param string $data 原文内容
*
* @return string
*/
function sign($data)
{
$filePath = 'private.pfx';
if(!file_exists($filePath)) {
return false;
}
$pkcs12 = file_get_contents($filePath);
if (openssl_pkcs12_read($pkcs12, $certs, '读取证书所需要的密码')) {
$privateKey = $certs['pkey']; //根据实际情况键值可能不同
$binary_signature = "";
if (openssl_sign(utf8_encode($data), $binarySignature, $privateKey, OPENSSL_ALGO_SHA1)) {
return bin2hex($binarySignature);
} else {
return '';
}
} else {
return '';
}
}
/**
* 验证签名自己生成的是否正确
*
* @param string $data 签名的原文
* @param string $signature 签名
*
* @return bool
*/
function verifySign($data, $signature)
{
$filePath = 'private.pfx';
if(!file_exists($filePath)) {
return false;
}
$pkcs12 = file_get_contents($filePath);
if (openssl_pkcs12_read($pkcs12, $certs, '读取证书所需要的密码')) {
$publicKey = $certs['cert'];
$ok = openssl_verify($data, hex2bin($signature), $publicKey);
if ($ok == 1) {
return true;
}
}
return false;
}
/**
* 验证返回的签名是否正确
* @filePath 为cer文件路径
* @param string $data 要验证的签名原文
* @param string $signature 签名内容
*
* @return bool
*/
function verifyRespondSign($data, $signature)
{
$filePath = 'public.cer';
if(!file_exists($filePath)) {
return false;
}
$cert = file_get_contents($filePath);
$$pubKeyId = openssl_get_publickey($cert);
$signature = hex2bin($signature);
$ok = openssl_verify(utf8_encode($data), $signature, $pubKeyId);
if ($ok == 1) {
openssl_free_key($pubkeyid);
return true;
}
return false;
}
?>
网友评论