mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 21:03:17 +08:00
122 lines
6.8 KiB
PHP
122 lines
6.8 KiB
PHP
|
|
<?php
|
|||
|
|
/**
|
|||
|
|
* 验证能否解密建行提供的demo加密串
|
|||
|
|
* 这是最直接的验证方法!
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
// 定义应用目录
|
|||
|
|
define('APP_PATH', __DIR__ . '/application/');
|
|||
|
|
|
|||
|
|
// 加载框架引导文件
|
|||
|
|
require __DIR__ . '/thinkphp/base.php';
|
|||
|
|
|
|||
|
|
// 手动引入需要的类文件
|
|||
|
|
require __DIR__ . '/addons/shopro/library/ccblife/CcbRSA.php';
|
|||
|
|
require __DIR__ . '/addons/shopro/library/ccblife/CcbMD5.php';
|
|||
|
|
|
|||
|
|
use addons\shopro\library\ccblife\CcbRSA;
|
|||
|
|
use addons\shopro\library\ccblife\CcbMD5;
|
|||
|
|
|
|||
|
|
echo "\n========== 验证能否解密建行demo加密串 ==========\n\n";
|
|||
|
|
|
|||
|
|
// 建行提供的demo数据(来自doc/demo/服务方上送报文样例.txt)
|
|||
|
|
$demoPublicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC+8V1Or6R6H3a7TjuvoDa5k0W/niEGg4N+0Nni+KfwHVX05pI7Qdq1J5+q31yORAoiSSNZNW4uWykmeSltC2mHGkQXClU4JmMXnWFyRCENw1iDIIIEsNax4jFBZUaDCn69PxWgp5wwk+d0V7QRYZ9jkgUaJK+BSYa0KMraxVfJwIDAQAB';
|
|||
|
|
$demoPrivateKey = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAML7xXU6vpHofdrtOO6+gNrmTRb+eIQaDg37Q2eL4p/AdVfTmkjtB2rUnn6rfXI5ECiJJI1k1bi5bKSZ5KW0LaYcaRBcKVTgmYxedYXJEIQ3DWIMgggSw1rHiMUFlRoMKfr0/FaCnnDCT53RXtBFhn2OSBRokr4FJhrQoytrFV8nAgMBAAECgYEAizhN0thw/altQ4YiIoWvZ50M6iAkWN5prp37kNGWrM40etNB1FQ5+ZN636L+3THVUbwqdzLKTy1GX3jqg05VUIf0sKYYepp+skwZmHVprz4EUKsZXRa+3MnMChJcyHdlyuUNs6HriMq6Qc1+fFEOtZFAf3lo2wYNFw5vIKHGQRECQQDxVKa+6m4y7LmWgiGLYghuL/SGXySFhwBh5+zMNl8V7aAbTX/tH6A0s8JXsSI4iChjWPXthKFTrd7h62vJBjeFAkEAztXpNehF18g3e6JEhtjbTmMsgyj13gdSZSRwjO0Y+IsDI1afnZXzwv96OlukGK8185z0bsbhTCOd6rkcRTnduwJBAOqGknlMh4VTylO66PB0d67lSaPgCDT/al67LcOTPzqnMAX4fc6qAl3VJ5Ni39fCckWB6ZVGZCVW/hfdWmUEdqUCQFFWNXuJd82/YnIwAZq1tKhCv8JkXSuO3YwApHIG2wcCQ52l9ubVjSJlrP8+Am3imOjQFB9r/jUe3H7thHyEoPkCQCay3waa0ll2DY+epkrrF/QO7aMa6NIUArRgWUmqw+1/45csBiWPMUrAD/CPDUr9Jvte92NjoAlz649csbgMM3w=';
|
|||
|
|
|
|||
|
|
// 建行提供的原始报文(明文)
|
|||
|
|
$expectedPlaintext = '{"CLD_HEADER":{"CLD_TX_CHNL":"YSTEST","CLD_TX_TIME":"20191112145911","CLD_TX_CODE":"A3341O031","CLD_TX_SEQ":"1010114131620697023913271"},"CLD_BODY":{"USER_ID":"user123","ORDER_ID":"order123","ORDER_DT":"20191112145811","TOTAL_AMT":"100.00","PAY_AMT":"90.00","DISCOUNT_AMT":"10.00","ORDER_STATUS":"1","REFUND_STATUS":"0","MCT_NM":"XXX商户"}}';
|
|||
|
|
|
|||
|
|
// 建行提供的加密报文(密文cnt字段)
|
|||
|
|
$demoCiphertext = 'Y2tFMDFJd2RGMGg5aFdXUGtjVVdaSmo4NHBKQzNNZE1wQTRRSXZVRlhBSWhqVEdXNE1LcE9MOXdxY0hhNUlIZndUU0RLK3NrZ1hpTytJUitpREEwSUp0bktRcWMxRG5hN1R0OEtjcUkxTUFDVE5FY2Z0b3lCeTVTaEo3cmNjSnBOUVFsSjRBR2htSzRheEhNb0p6N215eFViK1ZjeGd5WjVTTjJQcHUxQlBnZXJsQXE2Q1lrQ2VuSmZEYUxVSks5RGx2Yk9YWDlDczJiVVllYjlHSHQrUkFuYTljc2hucGhqVWNwNDgrcThNcGhQOElBL20xNVk5NG9lZEV4SXpmc0pDcDExZjFvQ0E5YkwwOWJOZjM4VHR3TkJkTmhqM3lKSVpWeWVpT0FucGhjS3JpOEs5RnlZbXlNVHF1UER3UjhmQ0p5dk5vYkNMS1BPRmQ3WFdXTVczZ29kSWpLaG5OUnhnaFA3N2txdDU3K2Rkd3hGbDgxUEdYbXJWN1ZKWDFOeXRVUFg2dWp3ZzdsUU1OSTlubU1kVE9nbHZJUHRoS205aEludFc2ZFBVTG1DUlNLNzZDc05qTUIyb1hTR2M2cHBNazMxNDJSa05KR0hvY1ZBNFUzcmc4SVk4ZFlYaTUzZmF3cHRES3pHY2JZVFI0SldRVzRNU2ZmSUxvNFpxTkY=';
|
|||
|
|
|
|||
|
|
// 建行提供的MAC签名
|
|||
|
|
$demoMac = '947CAB4DFEBE59265DD28246E4465157';
|
|||
|
|
|
|||
|
|
echo "【步骤1】验证MAC签名\n";
|
|||
|
|
echo "----------------------------------------\n";
|
|||
|
|
try {
|
|||
|
|
$calculatedMac = CcbMD5::signApiMessage($expectedPlaintext, $demoPrivateKey);
|
|||
|
|
echo "原始明文(前100字符):\n" . substr($expectedPlaintext, 0, 100) . "...\n\n";
|
|||
|
|
echo "建行提供的MAC: $demoMac\n";
|
|||
|
|
echo "我们计算的MAC: $calculatedMac\n";
|
|||
|
|
echo "MAC验证结果: " . ($calculatedMac === $demoMac ? "✓ 完全一致" : "✗ 不匹配") . "\n\n";
|
|||
|
|
|
|||
|
|
if ($calculatedMac !== $demoMac) {
|
|||
|
|
echo "⚠️ MAC签名不一致,可能原因:\n";
|
|||
|
|
echo " 1. MD5签名算法实现有误\n";
|
|||
|
|
echo " 2. 私钥格式处理有问题\n";
|
|||
|
|
echo " 3. 明文中有特殊字符编码问题\n\n";
|
|||
|
|
}
|
|||
|
|
} catch (Exception $e) {
|
|||
|
|
echo "✗ MAC签名失败: " . $e->getMessage() . "\n\n";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
echo "【步骤2】尝试解密建行提供的密文\n";
|
|||
|
|
echo "----------------------------------------\n";
|
|||
|
|
try {
|
|||
|
|
// 尝试用demo私钥解密
|
|||
|
|
echo "密文(cnt字段,前100字符):\n" . substr($demoCiphertext, 0, 100) . "...\n\n";
|
|||
|
|
echo "密文总长度: " . strlen($demoCiphertext) . " 字节\n";
|
|||
|
|
echo "开始解密...\n\n";
|
|||
|
|
|
|||
|
|
$decrypted = CcbRSA::decrypt($demoCiphertext, $demoPrivateKey);
|
|||
|
|
|
|||
|
|
echo "✓ 解密成功!\n\n";
|
|||
|
|
echo "解密后的明文:\n";
|
|||
|
|
echo $decrypted . "\n\n";
|
|||
|
|
|
|||
|
|
echo "========== 对比验证 ==========\n";
|
|||
|
|
echo "原始明文长度: " . strlen($expectedPlaintext) . " 字节\n";
|
|||
|
|
echo "解密明文长度: " . strlen($decrypted) . " 字节\n";
|
|||
|
|
echo "内容完全一致: " . ($decrypted === $expectedPlaintext ? "✓ 是" : "✗ 否") . "\n\n";
|
|||
|
|
|
|||
|
|
if ($decrypted === $expectedPlaintext) {
|
|||
|
|
echo "========== 🎉 验证成功! ==========\n\n";
|
|||
|
|
echo "【结论】\n";
|
|||
|
|
echo "✓ 我们的RSA解密代码完全正确\n";
|
|||
|
|
echo "✓ 我们的MD5签名代码完全正确\n";
|
|||
|
|
echo "✓ 能够正确解密建行提供的标准密文\n\n";
|
|||
|
|
echo "【这说明什么?】\n";
|
|||
|
|
echo "1. 代码逻辑没有问题\n";
|
|||
|
|
echo "2. 489错误不是代码问题,而是配置问题!\n";
|
|||
|
|
echo "3. 最可能的原因:\n";
|
|||
|
|
echo " - 你的公钥未在建行备案\n";
|
|||
|
|
echo " - 服务方编号(YS44000009001853)与密钥不匹配\n";
|
|||
|
|
echo " - 需要使用建行提供的平台公钥加密(而不是商户公钥)\n\n";
|
|||
|
|
|
|||
|
|
echo "【建议行动】\n";
|
|||
|
|
echo "1. 联系建行确认你的公钥是否已备案\n";
|
|||
|
|
echo "2. 确认服务方编号是否正确\n";
|
|||
|
|
echo "3. 询问建行:API加密应该用商户公钥还是建行平台公钥\n\n";
|
|||
|
|
} else {
|
|||
|
|
echo "⚠️ 解密内容与原始明文不一致\n\n";
|
|||
|
|
echo "差异分析:\n";
|
|||
|
|
echo "预期: " . substr($expectedPlaintext, 0, 100) . "...\n";
|
|||
|
|
echo "实际: " . substr($decrypted, 0, 100) . "...\n\n";
|
|||
|
|
|
|||
|
|
// 逐字符对比找出差异位置
|
|||
|
|
$len = min(strlen($expectedPlaintext), strlen($decrypted));
|
|||
|
|
for ($i = 0; $i < $len; $i++) {
|
|||
|
|
if ($expectedPlaintext[$i] !== $decrypted[$i]) {
|
|||
|
|
echo "首个差异位置: 第 $i 个字符\n";
|
|||
|
|
echo "预期字符: '" . $expectedPlaintext[$i] . "' (ASCII: " . ord($expectedPlaintext[$i]) . ")\n";
|
|||
|
|
echo "实际字符: '" . $decrypted[$i] . "' (ASCII: " . ord($decrypted[$i]) . ")\n";
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (Exception $e) {
|
|||
|
|
echo "✗ 解密失败: " . $e->getMessage() . "\n\n";
|
|||
|
|
echo "【可能原因】\n";
|
|||
|
|
echo "1. RSA解密算法实现有误\n";
|
|||
|
|
echo "2. 密钥格式处理有问题\n";
|
|||
|
|
echo "3. BASE64解码有问题\n";
|
|||
|
|
echo "4. PKCS1 Padding处理有误\n\n";
|
|||
|
|
echo "【调试信息】\n";
|
|||
|
|
echo "PHP版本: " . PHP_VERSION . "\n";
|
|||
|
|
echo "OpenSSL版本: " . OPENSSL_VERSION_TEXT . "\n\n";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
echo "========== 测试完成 ==========\n\n";
|