支付寶某些業務只能使用公鑰證照
方式來驗籤,但是隻有JAVA版本的SDK。所以轉載一下大佬們做的PHP版本SDK供大家使用。
原文地址:https://developer.aliyun.com/ask/138868 ,要往下翻一點,2019-09-12 13:28:54日使用者1628209366284721
發的帖。
function getRootCertSN($str)
{
// return '687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6';
$arr = preg_split('/(?=-----BEGIN)/', $str, -1, PREG_SPLIT_NO_EMPTY);
$str = null;
foreach ($arr as $e) {
$sn = getCertSN($e, true);
if (!$sn) {
continue;
}
if ($str === null) {
$str = $sn;
} else {
$str .= "_" . $sn;
}
}
return $str;
}
function getCertSN($str, $matchAlgo = false)
{
/*
根據java SDK原始碼:AntCertificationUtil::getRootCertSN
對證照鏈中RSA的專案進行過濾(猜測是gm國密演算法java拋錯搞不定,故意略去)
java原始碼為:
if(c.getSigAlgOID().startsWith("1.2.840.113549.1.1"))
根據 https://www.alvestrand.no/objectid/1.2.840.113549.1.1.html
該OID為RSA演算法系。
*/
if ($matchAlgo) {
openssl_x509_export($str, $out, false);
if (!preg_match('/Signature Algorithm:.*?RSA/im', $out, $m)) {
return;
}
}
$a = openssl_x509_parse($str);
$issuer = null;
// 注意:根據java程式碼輸出,需要倒著排列 CN,OU,O
foreach ($a["issuer"] as $k => $v) {
if ($issuer === null) {
$issuer = "$k=$v";
} else {
$issuer = "$k=$v," . $issuer;
}
}
# echo($issuer . $a["serialNumber"] . "\n");
$serialNumberHex = decimalNotation($a['serialNumberHex']);
$sn = md5($issuer . $serialNumberHex);
return $sn;
}
function decimalNotation($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;
}
然後在公共請求引數裡面傳遞app_cert_sn
和alipay_root_cert_sn
兩個引數即可。
原創。 所有 Laravel 文章均已收錄至 Github laravel-tips 專案。