微信企业付款到银行卡需要对收款方银行卡号、收款方用户名进行加密,这个过程需要获取到加密公钥
对于一些第一次接刚触到的小伙伴来说,可能比较陌生,在此记录一下自己生成 RSA公钥的过程。
1、调用官方提供的接口,接口默认输出PKCS#1格式的公钥
获取RSA公钥API获取RSA公钥
public function createRsaKey() {
$data = [
'mch_id' => '写自己的商户ID', // 商户ID
'nonce_str' => md5(time()),
'sign_type' => 'MD5',
];
$pay_api_key = '写自己的密钥'; // 密钥
//签名
$data["sign"] = $this->appgetSign($data, $pay_api_key);
$url = 'https://fraud.mch.weixin.qq.com/risk/getpublickey';
$data = $this->arrayToXml($data, true);
$postResult = $this->postCurl($url, $data);
$postResult = simplexml_load_string($postResult, 'SimpleXMLElement', LIBXML_NOCDATA);
// 保存成PEM文件,
file_put_contents('/自己的路径/名称.pem', $postResult->pub_key);
}
2、格式化参数格式化成url参数 生成签名sign
//格式化参数格式化成url参数 生成签名sign
public function appgetSign($Obj, $appwxpay_key, $bool = true) {
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters); // ksort — 对数组按照键名排序
$String = $this->formatBizQueryParaMap($Parameters, false);
//签名步骤二:在string后加入KEY
if ($appwxpay_key) {
$String = $String . "&key=" . $appwxpay_key;
}
if ($bool) {
//签名步骤三:MD5加密
$String = md5($String);
} else {
//HMAC-SHA256签名方式
$String = hash_hmac("sha256", $String, $appwxpay_key);
}
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
3、按字典序排序参数
//按字典序排序参数
public function formatBizQueryParaMap($paraMap, $urlencode) {
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if ($urlencode) {
$v = urlencode($v); //urlencode — 编码 URL 字符串
}
//$buff .= strtolower($k) . "=" . $v . "&";
$buff .= $k . "=" . $v . "&";
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
4、将数组转换为xml格式
//将数组转换为xml格式
public function arrayToXml($arr, $bool) {
$xml = "<xml>";
foreach ($arr as $key => $val) {
if ($bool) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
5、发送到微信post方法
function postCurl($url, $postData, $second = 30, $aHeader = array()) {
// $cert、$key为自己的证书路径
// 注意:要用绝对路径、要用绝对路径、要用绝对路径
$cert = 'C:/certs/apiclient_cert.pem';
$key = 'C:/certs/apiclient_key.pem';
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, $cert);
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, $key);
if (count($aHeader) >= 1) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
}
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$data = curl_exec($ch);
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
return false;
}
}
注意:证书验证失败和curl返回错误码58,问题原因:是微信支付的证书的路径必须是绝对路径
成功返回的数据如下
返回的PKCS#1格式的公钥 文件如下
6、PKCS#1 转 PKCS#8
命令:openssl rsa -RSAPublicKey_in -in 调用微信接口生成的文件名.pem -pubout > 自己命名一个公钥名称.pem
如:openssl rsa -RSAPublicKey_in -in pubkey.pem -pubout > public.pem
我是 鼠标右键 用 Git Bash Here
生成的PKCS#8公钥格式
【微信支付】付款开发者文档
在线RSA PKCS#1、PKCS#8公钥格式转换工具-ME2在线工具