fengketrade/addons/shopro/test/diagnose_ccb_encryption.php

153 lines
5.3 KiB
PHP
Raw Normal View History

2025-10-20 10:37:59 +08:00
<?php
/**
* 诊断建行加密方式
* 尝试不同的解密方法
*/
require_once __DIR__ . '/../library/ccblife/CcbRSA.php';
use addons\shopro\library\ccblife\CcbRSA;
echo "========================================\n";
echo " 建行加密方式诊断\n";
echo "========================================\n\n";
// 从.env读取密钥
$envFile = __DIR__ . '/../../../.env';
$envLines = file($envFile, FILE_IGNORE_NEW_LINES);
$privateKey = '';
$publicKey = '';
foreach ($envLines as $line) {
if (stripos($line, 'private_key=') === 0) {
$privateKey = trim(substr($line, 12));
}
if (stripos($line, 'public_key=') === 0) {
$publicKey = trim(substr($line, 11));
}
}
echo "1. 密钥信息\n";
echo " 私钥长度: " . strlen($privateKey) . "\n";
echo " 公钥长度: " . strlen($publicKey) . "\n\n";
// 步骤1: 验证密钥对是否配对
echo "2. 验证密钥对是否配对\n";
try {
$testData = "test=123&name=hello";
$encrypted = CcbRSA::encrypt($testData, $publicKey);
$decrypted = CcbRSA::decrypt($encrypted, $privateKey);
if ($decrypted === $testData) {
echo " ✅ 密钥对配对正确\n\n";
} else {
echo " ❌ 密钥对不匹配\n\n";
exit;
}
} catch (\Exception $e) {
echo " ❌ 密钥验证失败: " . $e->getMessage() . "\n\n";
exit;
}
// 建行的加密参数
$ccbParamSJ = 'cURYdUJxQ2pJTlVWQUltSW9DQWN1T2xJeFI4WjR2ZVY0NENTVmxPQW9RUVJ1bnJ2Ync5MkwzS2dXdDF1TTVSd3NvUFlsZWFURlYvK243aFNGaWRNeTJsZXRxM1VJR2k0VFdqNnU0Z2JXRnVxMnVIcjhzSVcrRW4xOGxaWDA4Snk0VW1hcFllZ05pekxmc2h6dGFCOTloTUtnVXh2ekJNbDFXZzdwT3lOcDBHZGx5N0FidW1FY1NudmlhNGcxZFAwM09BRk5sUE9USkM4QlJNNWtGTzRKVjFqTWx6RlhrblNwWG0rYmxpS2kyOFpYLy91OGZCR1NPNGp2dHN6b3N1TGxNZnUzd2JNeVUyOVpFTzYxWDRyNm0yb2c0ekZCQWpjc1VLdU9Kcmh1VjVwVDdQZlBlQ0MwRWhLQXFWWXBOdi9uS0FQNkZkZ2JER0ljN2tlUXNHdlFMTWlDeU9rVzdFU2phdG5jYjhZOUNaWkVEb29OdGVLdmlscXg4eHRFS1VtWHljU2ZNeUlDbk5yRW5nR3VXS1AvN3NacTNISE5BWSt2azBHdU1IaG5UWkl6bTdXUmhVYnNRclRYb0ljNy9UTnZVT3lmSVFIcTZ0KzZpZGdtc1NDejBkajVsSjkzVXNSM0NWZExCUk85NHQxZGNEOWorUnFhV2hrWmpiYUE4SlY=';
echo "3. 尝试不同的解密方法\n\n";
// 方法1: 标准RSA解密用商户私钥
echo "方法1: 使用商户私钥解密(标准方式)\n";
try {
$urlDecoded = urldecode($ccbParamSJ);
$decrypted = CcbRSA::decrypt($urlDecoded, $privateKey);
echo " 解密成功,长度: " . strlen($decrypted) . "\n";
// 检查是否是可打印字符
$isPrintable = ctype_print($decrypted);
echo " 是否为可打印字符: " . ($isPrintable ? '是' : '否') . "\n";
if ($isPrintable) {
echo " 解密内容: {$decrypted}\n";
parse_str($decrypted, $params);
if (!empty($params)) {
echo " ✅ 解析成功!参数:\n";
foreach ($params as $k => $v) {
echo " {$k} = {$v}\n";
}
}
} else {
echo " 内容预览(十六进制): " . bin2hex(substr($decrypted, 0, 50)) . "...\n";
echo " ❌ 解密结果不是有效文本\n";
}
} catch (\Exception $e) {
echo " ❌ 解密失败: " . $e->getMessage() . "\n";
}
echo "\n";
// 方法2: 尝试用公钥解密(建行可能用建行私钥加密)
echo "方法2: 尝试用商户公钥解密(反向,测试建行是否用私钥加密)\n";
try {
$urlDecoded = urldecode($ccbParamSJ);
// 格式化公钥为PEM
$pemPublicKey = "-----BEGIN PUBLIC KEY-----\n";
$pemPublicKey .= chunk_split($publicKey, 64, "\n");
$pemPublicKey .= "-----END PUBLIC KEY-----\n";
$pubKeyResource = openssl_pkey_get_public($pemPublicKey);
if (!$pubKeyResource) {
throw new \Exception('公钥格式错误');
}
// BASE64解码
$encryptedData = base64_decode($urlDecoded);
// 获取密钥大小
$keyDetails = openssl_pkey_get_details($pubKeyResource);
$keySize = $keyDetails['bits'] / 8;
// 分块解密
$dataBlocks = str_split($encryptedData, $keySize);
$decrypted = '';
foreach ($dataBlocks as $block) {
$decryptedBlock = '';
// 尝试用公钥解密
$success = @openssl_public_decrypt($block, $decryptedBlock, $pubKeyResource, OPENSSL_PKCS1_PADDING);
if (!$success) {
throw new \Exception('公钥解密失败');
}
$decrypted .= $decryptedBlock;
}
openssl_free_key($pubKeyResource);
echo " 解密成功,长度: " . strlen($decrypted) . "\n";
$isPrintable = ctype_print($decrypted);
echo " 是否为可打印字符: " . ($isPrintable ? '是' : '否') . "\n";
if ($isPrintable) {
echo " 解密内容: {$decrypted}\n";
echo " ✅ 可能建行用的是建行私钥加密!\n";
} else {
echo " ❌ 解密结果不是有效文本\n";
}
} catch (\Exception $e) {
echo " ❌ 解密失败: " . $e->getMessage() . "\n";
}
echo "\n";
// 方法3: 检查是否需要建行公钥
echo "方法3: 建议检查项\n";
echo " - 确认建行后台配置的商户公钥是否为:\n";
echo " " . substr($publicKey, 0, 50) . "...\n";
echo " - 检查建行是否提供了建行平台公钥(用于解密建行发来的数据)\n";
echo " - 联系建行技术支持确认ccbParamSJ的加密方式\n";
echo "\n========================================\n";
echo "诊断完成\n";
echo "========================================\n";