diff --git a/src/AlipayApp/Params/PublicParams.php b/src/AlipayApp/Params/PublicParams.php index d39aa54..829faa2 100644 --- a/src/AlipayApp/Params/PublicParams.php +++ b/src/AlipayApp/Params/PublicParams.php @@ -69,6 +69,34 @@ class PublicParams extends PublicBase */ public $aesKey; + /** + * 是否使用公钥证书模式 + * + * @var boolean + */ + public $usePublicKeyCert = false; + + /** + * 支付宝公钥证书文件路径 + * + * @var string + */ + public $alipayCertPath; + + /** + * 支付宝根证书文件路径 + * + * @var string + */ + public $alipayRootCertPath; + + /** + * 支付宝应用公钥证书文件路径 + * + * @var string + */ + public $merchantCertPath; + public function __construct() { $this->apiDomain = 'https://openapi.alipay.com/gateway.do'; diff --git a/src/AlipayApp/SDK.php b/src/AlipayApp/SDK.php index c2ed32f..f80c3be 100644 --- a/src/AlipayApp/SDK.php +++ b/src/AlipayApp/SDK.php @@ -2,6 +2,7 @@ namespace Yurun\PaySDK\AlipayApp; use \Yurun\PaySDK\Base; +use Yurun\PaySDK\Lib\CertUtil; use \Yurun\PaySDK\Lib\Encrypt\AES; use \Yurun\PaySDK\Lib\ObjectToArray; @@ -16,6 +17,43 @@ class SDK extends Base */ public $publicParams; + /** + * 支付宝公钥证书SN + * + * @var string + */ + public $alipayCertSn; + + /** + * 应用公钥证书SN + * + * @var string + */ + public $appCertSn; + + /** + * 支付宝根证书SN + * + * @var string + */ + public $alipayRootCertSn; + + /** + * __construct + * + * @param \Yurun\PaySDK\AlipayApp\Params\PublicParams $publicParams + */ + public function __construct($publicParams) + { + parent::__construct($publicParams); + if($publicParams->usePublicKeyCert) + { + $this->alipayCertSn = CertUtil::getCertSN($publicParams->alipayCertPath); + $this->appCertSn = CertUtil::getCertSN($publicParams->merchantCertPath); + $this->alipayRootCertSn = CertUtil::getRootCertSN($publicParams->alipayRootCertPath); + } + } + /** * 处理执行接口的数据 * @param $params @@ -27,13 +65,19 @@ class SDK extends Base public function __parseExecuteData($params, &$data, &$requestData, &$url) { $data = \array_merge(ObjectToArray::parse($this->publicParams), ObjectToArray::parse($params)); - unset($data['apiDomain'], $data['appID'], $data['businessParams'], $data['appPrivateKey'], $data['appPrivateKeyFile'], $data['appPublicKey'], $data['appPublicKeyFile'], $data['_syncResponseName'], $data['_method'], $data['_isSyncVerify'], $data['aesKey'], $data['isUseAES']); + unset($data['apiDomain'], $data['appID'], $data['businessParams'], $data['appPrivateKey'], $data['appPrivateKeyFile'], $data['appPublicKey'], $data['appPublicKeyFile'], $data['_syncResponseName'], $data['_method'], $data['_isSyncVerify'], $data['aesKey'], $data['isUseAES'], $data['alipayCertPath'], $data['alipayRootCertPath'], $data['merchantCertPath'], $data['usePublicKeyCert']); $data['app_id'] = $this->publicParams->appID; $data['biz_content'] = $params->businessParams->toString(); if($this->publicParams->isUseAES) { $data['biz_content'] = AES::encrypt($data['biz_content'], \base64_decode($this->publicParams->aesKey)); } + // 公钥证书参数 + if($this->publicParams->usePublicKeyCert) + { + $data['app_cert_sn'] = $this->appCertSn; + $data['alipay_root_cert_sn'] = $this->alipayRootCertSn; + } $data['timestamp'] = date('Y-m-d H:i:s'); $data['sign'] = $this->sign($data); $requestData = $data; @@ -119,6 +163,11 @@ public function verifySync($params, $data) { return true; } + // 公钥证书验证 + if($this->publicParams->usePublicKeyCert && $this->alipayCertSn !== (isset($data['alipay_cert_sn']) ? $data['alipay_cert_sn'] : null)) + { + return false; + } $content = \json_encode($data[$params->_syncResponseName], JSON_UNESCAPED_UNICODE); if(empty($this->publicParams->appPublicKeyFile)) { diff --git a/src/Lib/CertUtil.php b/src/Lib/CertUtil.php new file mode 100644 index 0000000..7aa7998 --- /dev/null +++ b/src/Lib/CertUtil.php @@ -0,0 +1,91 @@ + $value) + { + $string[] = $key . '=' . $value; + } + } + return implode(',', $string); + } + + /** + * 0x转高精度数字 + * @param $hex + * @return int|string + */ + public static function hex2dec($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; + } + +} diff --git a/test/AlipayApp/ftf_pay.php b/test/AlipayApp/ftf_pay.php index e389c4f..0200343 100644 --- a/test/AlipayApp/ftf_pay.php +++ b/test/AlipayApp/ftf_pay.php @@ -9,6 +9,13 @@ $params->appID = $GLOBALS['PAY_CONFIG']['appid']; $params->appPrivateKey = $GLOBALS['PAY_CONFIG']['privateKey']; $params->appPublicKey = $GLOBALS['PAY_CONFIG']['publicKey']; + +// 公钥证书演示 +$params->usePublicKeyCert = true; +$params->alipayCertPath = __DIR__ . '/cert/alipayCertPublicKey_RSA2.crt'; +$params->alipayRootCertPath = __DIR__ . '/cert/alipayRootCert.crt'; +$params->merchantCertPath = __DIR__ . '/cert/appCertPublicKey_2016073000123475.crt'; + // $params->appPrivateKeyFile = ''; // 证书文件,如果设置则这个优先使用 $params->apiDomain = 'https://openapi.alipaydev.com/gateway.do'; // 设为沙箱环境,如正式环境请把这行注释