fengketrade/addons/shopro/test/diagnose_ccb_encryption.php
2025-10-20 10:37:59 +08:00

153 lines
5.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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";