首发php版支付宝公钥证书
从java代码中搬过来的,对官方的文档很无语,坑太多了
官方文档[https://docs.open.alipay.com/291/106118]里面是这样写的:
说明:
公钥证书方式下,开发者发送给开放平台网关请求参数中,需携带应用公钥证书SN(app_cert_sn)、支付宝根证书SN(alipay_root_cert_sn),若不携带这两个参数,网关会拒绝请求。SN值是通过解析X.509证书文件中签发机构名称(name)以及内置序列号(serialNumber),将二者拼接后的字符串计算MD5值获取,可参考开放平台SDK源码中AlipaySignature.getCertSN实现app_cert_sn的提取
注意点:
- 解析X.509证书文件中签发机构名称是什么玩意,php解析出来的是个数组!到底哪个是的,是什么格式的?
- 拼接MD5,不读java代码,打死也猜不出来支付宝根证书和应用证书的方法是不一样的
php解析出来的
PHP生成SN源码
应用证书解析格式如下
需要拼接成:CN=Ant Financial Certification Authority Class 2 R1,OU=Certification Authority,O=Ant Financial,C=CN
支付宝根证书
要拆解成多个证书,分别解析并生成MD5,最后用"_"拼接
注意:serialNumber序列号可能会出现0x开头的,需要转换一下
代码
/**
* 生成应用证书SN
* @param $certPath
* @return string
* @throws /Exception
*/
public static function getCertSN($certPath): string
{
if (!is_file($certPath)) {
throw new \Exception('unknown certPath -- [getCertSN]');
}
$x509data = file_get_contents($certPath);
if ($x509data === false) {
throw new \Exception('Alipay CertSN Error -- [getCertSN]');
}
openssl_x509_read($x509data);
$certdata = openssl_x509_parse($x509data);
if (empty($certdata)) {
throw new \Exception('Alipay openssl_x509_parse Error -- [getCertSN]');
}
$issuer_arr = [];
foreach ($certdata['issuer'] as $key => $val) {
$issuer_arr[] = $key . '=' . $val;
}
$issuer = implode(',', array_reverse($issuer_arr));
Log::debug('getCertSN:', [$certPath, $issuer, $certdata['serialNumber']]);
return md5($issuer . $certdata['serialNumber']);
}
/**
* 0x转高精度数字
* @param $hex
* @return int|string
*/
private static function bchexdec($hex)
{
$dec = 0;
$len = strlen($hex);
for ($i = 1; $i <= $len; $i++) {
$dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
}
return $dec;
}
/**
* 生成支付宝根证书SN
* @param $certPath
* @return string
* @throws /Exception
*/
public static function getRootCertSN($certPath)
{
if (!is_file($certPath)) {
throw new \Exception('unknown certPath -- [getRootCertSN]');
}
$x509data = file_get_contents($certPath);
if ($x509data === false) {
throw new \Exception('Alipay CertSN Error -- [getRootCertSN]');
}
$kCertificateEnd = "-----END CERTIFICATE-----";
$certStrList = explode($kCertificateEnd, $x509data);
$md5_arr = [];
foreach ($certStrList as $one) {
if (!empty(trim($one))) {
$_x509data = $one . $kCertificateEnd;
openssl_x509_read($_x509data);
$_certdata = openssl_x509_parse($_x509data);
if (in_array($_certdata['signatureTypeSN'], ['RSA-SHA256', 'RSA-SHA1'])) {
$issuer_arr = [];
foreach ($_certdata['issuer'] as $key => $val) {
$issuer_arr[] = $key . '=' . $val;
}
$_issuer = implode(',', array_reverse($issuer_arr));
if (strpos($_certdata['serialNumber'], '0x') === 0) {
$serialNumber = self::bchexdec($_certdata['serialNumber']);
} else {
$serialNumber = $_certdata['serialNumber'];
}
$md5_arr[] = md5($_issuer . $serialNumber);
Log::debug('getRootCertSN Sub:', [$certPath, $_issuer, $serialNumber]);
}
}
}
return implode('_', $md5_arr);
}
8 条评论
《原始生活21天第四季》记录片高清在线免费观看:https://www.jgz518.com/xingkong/18469.html
《谋刺关东王》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/88877.html
兄弟,我这边也是系统提示ALIN10070
兄弟,这个函数不行啊,我是取出来了,但是系统提示ALIN10070
加我微信:s190520601
因为他们只给一周时间切换, 所以我还没敢申请公钥证书模式, 现在正在研究这个加密的事情, 你如果已经调通的话, 还望赐教, 不胜感激!我的微信号: dabing_yuyu
你好, 我也在用PHP对接支付宝证书, 另问下上面两个函数输入的 “应用证书” 和 “支付宝根证书”是从哪里拿到的?