mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 21:03:17 +08:00
生成支付串
This commit is contained in:
parent
1b725587e8
commit
80f2cdd84a
@ -74,39 +74,7 @@ return [
|
|||||||
* 📌 注意: 需要将此公钥提交给建行进行配置
|
* 📌 注意: 需要将此公钥提交给建行进行配置
|
||||||
* 📌 如果已上架建行生活并同步公钥,可以不再上送ENCPUB
|
* 📌 如果已上架建行生活并同步公钥,可以不再上送ENCPUB
|
||||||
*/
|
*/
|
||||||
'merchant_public_key' => $envVars['merchant_public_key'] ?? ($envVars['public_key'] ?? ''),
|
'merchant_public_key' => $envVars['merchant_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'] ?? '',
|
|
||||||
|
|
||||||
// HTTP请求配置
|
// HTTP请求配置
|
||||||
'http' => [
|
'http' => [
|
||||||
|
|||||||
@ -485,7 +485,12 @@ class CcbPaymentService
|
|||||||
/**
|
/**
|
||||||
* 格式化公钥为PEM格式
|
* 格式化公钥为PEM格式
|
||||||
*
|
*
|
||||||
* @param string $publicKey BASE64或PEM格式的公钥
|
* 支持三种输入格式:
|
||||||
|
* 1. PEM格式(已包含BEGIN/END标记)
|
||||||
|
* 2. BASE64格式(不含PEM头尾)
|
||||||
|
* 3. 十六进制格式(DER编码的十六进制字符串)
|
||||||
|
*
|
||||||
|
* @param string $publicKey 公钥(PEM/BASE64/HEX格式)
|
||||||
* @return string PEM格式的公钥
|
* @return string PEM格式的公钥
|
||||||
*/
|
*/
|
||||||
private function formatPublicKeyToPem($publicKey)
|
private function formatPublicKeyToPem($publicKey)
|
||||||
@ -498,6 +503,16 @@ class CcbPaymentService
|
|||||||
return $publicKey;
|
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格式
|
||||||
$pem = "-----BEGIN PUBLIC KEY-----\n";
|
$pem = "-----BEGIN PUBLIC KEY-----\n";
|
||||||
$pem .= rtrim(chunk_split($publicKey, 64, "\n"), "\n") . "\n";
|
$pem .= rtrim(chunk_split($publicKey, 64, "\n"), "\n") . "\n";
|
||||||
@ -747,11 +762,11 @@ class CcbPaymentService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查是否配置了建行支付验签公钥
|
// 2. 检查是否配置了建行支付验签公钥
|
||||||
$ccbVerifyPublicKey = $this->config['ccb_payment_verify_public_key'] ?? '';
|
$ccbVerifyPublicKey = $this->config['public_key'] ?? '';
|
||||||
|
|
||||||
if (empty($ccbVerifyPublicKey)) {
|
if (empty($ccbVerifyPublicKey)) {
|
||||||
// 降级方案: 未配置验签公钥时,使用POSID验证
|
// 降级方案: 未配置验签公钥时,使用POSID验证
|
||||||
Log::warning('[建行验签] 未配置ccb_payment_verify_public_key,使用降级验证方案');
|
Log::warning('[建行验签] 未配置public_key,使用降级验证方案');
|
||||||
|
|
||||||
// 验证POSID是否匹配
|
// 验证POSID是否匹配
|
||||||
if (($params['POSID'] ?? '') !== $this->config['pos_id']) {
|
if (($params['POSID'] ?? '') !== $this->config['pos_id']) {
|
||||||
|
|||||||
@ -46,7 +46,10 @@ class CcbRSA
|
|||||||
$encrypted .= $encryptedBlock;
|
$encrypted .= $encryptedBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PHP 8+ 资源自动释放
|
||||||
|
if (PHP_VERSION_ID < 80000) {
|
||||||
openssl_free_key($pubKey);
|
openssl_free_key($pubKey);
|
||||||
|
}
|
||||||
|
|
||||||
// 返回BASE64编码的结果
|
// 返回BASE64编码的结果
|
||||||
return base64_encode($encrypted);
|
return base64_encode($encrypted);
|
||||||
@ -92,7 +95,10 @@ class CcbRSA
|
|||||||
$decrypted .= $decryptedBlock;
|
$decrypted .= $decryptedBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PHP 8+ 资源自动释放
|
||||||
|
if (PHP_VERSION_ID < 80000) {
|
||||||
openssl_free_key($priKey);
|
openssl_free_key($priKey);
|
||||||
|
}
|
||||||
|
|
||||||
return $decrypted;
|
return $decrypted;
|
||||||
}
|
}
|
||||||
@ -272,7 +278,10 @@ class CcbRSA
|
|||||||
// 使用公钥验签(SHA256算法)
|
// 使用公钥验签(SHA256算法)
|
||||||
$result = openssl_verify($data, $signatureBinary, $pubKey, OPENSSL_ALGO_SHA256);
|
$result = openssl_verify($data, $signatureBinary, $pubKey, OPENSSL_ALGO_SHA256);
|
||||||
|
|
||||||
|
// PHP 8+ 资源自动释放
|
||||||
|
if (PHP_VERSION_ID < 80000) {
|
||||||
openssl_free_key($pubKey);
|
openssl_free_key($pubKey);
|
||||||
|
}
|
||||||
|
|
||||||
if ($result === 1) {
|
if ($result === 1) {
|
||||||
return true; // 验签成功
|
return true; // 验签成功
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user