Browse Source

优化支付宝证书

master
wuliangbo 5 years ago
parent
commit
538acbdfc6
  1. 2
      composer.json
  2. 15
      src/Kernel/AppClient.php
  3. 114
      src/Kernel/Traits/SingData.php

2
composer.json

@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
"ext-openssl": "*",
"ext-json": "*",
"ext-simplexml": "*",
"ext-ctype": "*",
"ext-bcmath": "*",
"guzzlehttp/guzzle": "^6.2",
"pimple/pimple": "^3.0",
"symfony/cache": "^3.3 || ^4.3",

15
src/Kernel/AppClient.php

@ -136,14 +136,13 @@ class AppClient extends BaseClient @@ -136,14 +136,13 @@ class AppClient extends BaseClient
/**
* @param AppRequest $request
* @param null $authToken
* @param null $appInfoAuthtoken
* @return Collection
* @throws BadRequestException
* @throws InvalidArgumentException
* @throws InvalidConfigException
* @throws InvalidSignException
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Exception
*/
public function execute(AppRequest $request)
{
@ -164,6 +163,12 @@ class AppClient extends BaseClient @@ -164,6 +163,12 @@ class AppClient extends BaseClient
$sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams), $this->signType);
$requestUrl = $this->buildRequestUrl($sysParams);
$result = $this->httpPost($requestUrl, $apiParams);
if(isset($result[$this->ERROR_RESPONSE])){ //返回错误
throw new BadRequestException(
'Get Alipay API Error:' . $result[$this->ERROR_RESPONSE]['msg'] .
(isset($result[$this->ERROR_RESPONSE]['sub_code']) ? (' - ' . $result[$this->ERROR_RESPONSE]['sub_code']) : '')
);
}
$apiName = $request->getApiMethodName();
$method = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX;
$content = $result[$method];
@ -186,6 +191,7 @@ class AppClient extends BaseClient @@ -186,6 +191,7 @@ class AppClient extends BaseClient
/**
* @param AppRequest $request
* @return array
* @throws \Exception
*/
protected function buildParams(AppRequest $request): array
{
@ -210,7 +216,10 @@ class AppClient extends BaseClient @@ -210,7 +216,10 @@ class AppClient extends BaseClient
if (isset($this->config['auth_token'])) {
$sysParams["auth_token"] = $this->config['auth_token'];
}
if ($this->app->config->get('app_cert_public_key') && $this->app->config->get('alipay_root_cert')) {
$sysParams['app_cert_sn'] = $this->getCertSN($this->app->config->get('app_cert_public_key'));
$sysParams['alipay_root_cert_sn'] = $this->getRootCertSN($this->app->config->get('alipay_root_cert'));
}
if (isset($this->config['app_auth_token'])) {
$sysParams["app_auth_token"] = $this->config['app_auth_token'];
}

114
src/Kernel/Traits/SingData.php

@ -29,13 +29,14 @@ trait SingData @@ -29,13 +29,14 @@ trait SingData
if (is_null($privateKey)) {
throw new InvalidConfigException('Missing Alipay Config -- [private_key]');
}
if (Str::endsWith($privateKey, '.pem')) {
$privateKey = openssl_pkey_get_private(
Str::startsWith($privateKey, 'file://') ? $privateKey : 'file://' . $privateKey
Str::startsWith($privateKey, 'file://') ? $privateKey : 'file://'.$privateKey
);
} else {
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($privateKey, 64, "\n", true) .
$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n".
wordwrap($privateKey, 64, "\n", true).
"\n-----END RSA PRIVATE KEY-----";
}
@ -64,13 +65,15 @@ trait SingData @@ -64,13 +65,15 @@ trait SingData
if (is_null($publicKey)) {
throw new InvalidConfigException('Missing Alipay Config -- [ali_public_key]');
}
if (Str::endsWith($publicKey, '.pem')) {
if (Str::endsWith($publicKey, '.crt')) {
$publicKey = file_get_contents($publicKey);
} elseif (Str::endsWith($publicKey, '.pem')) {
$publicKey = openssl_pkey_get_public(
Str::startsWith($publicKey, 'file://') ? $publicKey : 'file://' . $publicKey
Str::startsWith($publicKey, 'file://') ? $publicKey : 'file://'.$publicKey
);
} else {
$publicKey = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($publicKey, 64, "\n", true) .
$publicKey = "-----BEGIN PUBLIC KEY-----\n".
wordwrap($publicKey, 64, "\n", true).
"\n-----END PUBLIC KEY-----";
}
$data = json_encode($data, JSON_UNESCAPED_UNICODE);
@ -145,4 +148,101 @@ trait SingData @@ -145,4 +148,101 @@ trait SingData
return true;
return false;
}
/**
* 生成应用证书SN.
* @param $certPath
* @return string
* @throws \Exception
*/
public function getCertSN($certPath): string
{
if (!is_file($certPath)) {
throw new \Exception('unknown certPath -- [getCertSN]');
}
$x509data = file_get_contents($certPath);
if (false === $x509data) {
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));
return md5($issuer.$certdata['serialNumber']);
}
/**
* 生成支付宝根证书SN.
*
* @author 大冰 https://sbing.vip/archives/2019-new-alipay-php-docking.html
*
* @param $certPath
*
* @return string
*
* @throws /Exception
*/
public function getRootCertSN($certPath)
{
if (!is_file($certPath)) {
throw new \Exception('unknown certPath -- [getRootCertSN]');
}
$x509data = file_get_contents($certPath);
if (false === $x509data) {
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 (0 === strpos($_certdata['serialNumber'], '0x')) {
$serialNumber = self::bchexdec($_certdata['serialNumber']);
} else {
$serialNumber = $_certdata['serialNumber'];
}
$md5_arr[] = md5($_issuer.$serialNumber);
}
}
}
return implode('_', $md5_arr);
}
/**
* 0x转高精度数字.
*
* @author 大冰 https://sbing.vip/archives/2019-new-alipay-php-docking.html
*
* @param $hex
*
* @return int|string
*/
private static function bchexdec($hex)
{
$dec = 0;
$len = strlen($hex);
for ($i = 1; $i <= $len; ++$i) {
if (ctype_xdigit($hex[$i - 1])) {
$dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
}
}
return $dec;
}
}
Loading…
Cancel
Save