mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 12:57:32 +08:00
生成支付串
This commit is contained in:
parent
1b725587e8
commit
80f2cdd84a
@ -74,39 +74,7 @@ return [
|
||||
* 📌 注意: 需要将此公钥提交给建行进行配置
|
||||
* 📌 如果已上架建行生活并同步公钥,可以不再上送ENCPUB
|
||||
*/
|
||||
'merchant_public_key' => $envVars['merchant_public_key'] ?? ($envVars['public_key'] ?? ''),
|
||||
|
||||
/**
|
||||
* 建行平台API公钥 (建行生活平台提供的RSA公钥)
|
||||
* 用途:
|
||||
* - 加密API请求报文(A3341TP01/02/03/04等接口)
|
||||
* - 只有建行用自己的私钥才能解密
|
||||
* 获取方式: 联系建行生活平台技术支持获取
|
||||
* 格式: BASE64格式(不含PEM头尾) 或 PEM格式(含头尾)
|
||||
*
|
||||
* ⚠️ 重要说明:
|
||||
* 1. 如果未单独配置,将使用merchant_public_key(向下兼容)
|
||||
* 2. 建行可能为每个商户分配统一密钥对,或要求使用建行平台公钥
|
||||
* 3. 请联系建行确认应使用哪个公钥进行API请求加密
|
||||
*
|
||||
* 📋 RSA加密逻辑:
|
||||
* - 商户用建行公钥加密请求 → 建行用建行私钥解密
|
||||
* - 商户用商户私钥签名 → 建行用商户公钥验签
|
||||
*/
|
||||
'ccb_platform_public_key' => $envVars['ccb_platform_public_key'] ?? ($envVars['public_key'] ?? ''),
|
||||
|
||||
/**
|
||||
* 建行生活支付验签公钥 (建行生活平台分配的)
|
||||
* 用途:
|
||||
* - 验证异步通知中的SIGN字段(NT_TYPE=YS时)
|
||||
* 获取方式: 联系建行生活平台运营人员或技术支持
|
||||
* 格式: PEM格式RSA公钥(2048位)
|
||||
*
|
||||
* 📌 如果未配置此字段:
|
||||
* - 异步通知验签会降级为POSID验证
|
||||
* - 安全性降低,建议尽快获取并配置
|
||||
*/
|
||||
'ccb_payment_verify_public_key' => $envVars['ccb_payment_verify_public_key'] ?? '',
|
||||
'merchant_public_key' => $envVars['merchant_public_key'] ?? '',
|
||||
|
||||
// HTTP请求配置
|
||||
'http' => [
|
||||
|
||||
@ -485,7 +485,12 @@ class CcbPaymentService
|
||||
/**
|
||||
* 格式化公钥为PEM格式
|
||||
*
|
||||
* @param string $publicKey BASE64或PEM格式的公钥
|
||||
* 支持三种输入格式:
|
||||
* 1. PEM格式(已包含BEGIN/END标记)
|
||||
* 2. BASE64格式(不含PEM头尾)
|
||||
* 3. 十六进制格式(DER编码的十六进制字符串)
|
||||
*
|
||||
* @param string $publicKey 公钥(PEM/BASE64/HEX格式)
|
||||
* @return string PEM格式的公钥
|
||||
*/
|
||||
private function formatPublicKeyToPem($publicKey)
|
||||
@ -498,6 +503,16 @@ class CcbPaymentService
|
||||
return $publicKey;
|
||||
}
|
||||
|
||||
// ✅ 判断是否为十六进制格式(只包含0-9a-fA-F字符)
|
||||
if (ctype_xdigit($publicKey)) {
|
||||
// 十六进制格式 → 解码为二进制 → 转BASE64
|
||||
$binaryKey = hex2bin($publicKey);
|
||||
if ($binaryKey === false) {
|
||||
throw new \Exception('十六进制公钥解码失败');
|
||||
}
|
||||
$publicKey = base64_encode($binaryKey);
|
||||
}
|
||||
|
||||
// 转换为PEM格式
|
||||
$pem = "-----BEGIN PUBLIC KEY-----\n";
|
||||
$pem .= rtrim(chunk_split($publicKey, 64, "\n"), "\n") . "\n";
|
||||
@ -747,11 +762,11 @@ class CcbPaymentService
|
||||
}
|
||||
|
||||
// 2. 检查是否配置了建行支付验签公钥
|
||||
$ccbVerifyPublicKey = $this->config['ccb_payment_verify_public_key'] ?? '';
|
||||
$ccbVerifyPublicKey = $this->config['public_key'] ?? '';
|
||||
|
||||
if (empty($ccbVerifyPublicKey)) {
|
||||
// 降级方案: 未配置验签公钥时,使用POSID验证
|
||||
Log::warning('[建行验签] 未配置ccb_payment_verify_public_key,使用降级验证方案');
|
||||
Log::warning('[建行验签] 未配置public_key,使用降级验证方案');
|
||||
|
||||
// 验证POSID是否匹配
|
||||
if (($params['POSID'] ?? '') !== $this->config['pos_id']) {
|
||||
|
||||
@ -46,7 +46,10 @@ class CcbRSA
|
||||
$encrypted .= $encryptedBlock;
|
||||
}
|
||||
|
||||
openssl_free_key($pubKey);
|
||||
// PHP 8+ 资源自动释放
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
openssl_free_key($pubKey);
|
||||
}
|
||||
|
||||
// 返回BASE64编码的结果
|
||||
return base64_encode($encrypted);
|
||||
@ -92,7 +95,10 @@ class CcbRSA
|
||||
$decrypted .= $decryptedBlock;
|
||||
}
|
||||
|
||||
openssl_free_key($priKey);
|
||||
// PHP 8+ 资源自动释放
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
openssl_free_key($priKey);
|
||||
}
|
||||
|
||||
return $decrypted;
|
||||
}
|
||||
@ -272,7 +278,10 @@ class CcbRSA
|
||||
// 使用公钥验签(SHA256算法)
|
||||
$result = openssl_verify($data, $signatureBinary, $pubKey, OPENSSL_ALGO_SHA256);
|
||||
|
||||
openssl_free_key($pubKey);
|
||||
// PHP 8+ 资源自动释放
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
openssl_free_key($pubKey);
|
||||
}
|
||||
|
||||
if ($result === 1) {
|
||||
return true; // 验签成功
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user