0) { if ($inputLen - $offset > $maxEncryptBlock) { $block = substr($data, $offset, $maxEncryptBlock); } else { $block = substr($data, $offset, $inputLen - $offset); } $encryptedBlock = ''; // Java: cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK) // PHP等价: openssl_public_encrypt with PKCS1 padding $success = openssl_public_encrypt($block, $encryptedBlock, $publicKey, OPENSSL_PKCS1_PADDING); if (!$success) { throw new Exception("第{$i}段加密失败: " . openssl_error_string()); } $encrypted .= $encryptedBlock; $i++; $offset = $i * $maxEncryptBlock; echo " 加密第{$i}段: " . strlen($block) . " bytes -> " . strlen($encryptedBlock) . " bytes\n"; } openssl_free_key($publicKey); // Java: encodedDataStr = new String(encryptBASE64(encryptedData)); $base64Result = base64_encode($encrypted); echo " 总密文长度: " . strlen($encrypted) . " bytes\n"; echo " BASE64长度: " . strlen($base64Result) . " characters\n\n"; return $base64Result; } // Java RSAUtil.java 的 decrypt 方法 function rsaDecrypt($dataStr, $privateKeyStr) { // Java: byte[] encryptedData = decryptBASE64(dataStr); $encryptedData = base64_decode($dataStr); echo " BASE64解码后: " . strlen($encryptedData) . " bytes\n"; // 加载私钥 $privateKey = getPrivateKeyFromBase64($privateKeyStr); if (!$privateKey) { throw new Exception("私钥加载失败: " . openssl_error_string()); } // 获取密钥大小 $keyDetails = openssl_pkey_get_details($privateKey); $keySize = $keyDetails['bits'] / 8; $maxDecryptBlock = 128; // Java中定义的 MAX_DECRYPT_BLOCK echo " 密钥大小: {$keyDetails['bits']} bits ($keySize bytes)\n"; echo " 最大解密块: $maxDecryptBlock bytes\n"; // 分段解密 $decrypted = ''; $inputLen = strlen($encryptedData); $offset = 0; $i = 0; while ($inputLen - $offset > 0) { if ($inputLen - $offset > $maxDecryptBlock) { $block = substr($encryptedData, $offset, $maxDecryptBlock); } else { $block = substr($encryptedData, $offset, $inputLen - $offset); } $decryptedBlock = ''; // Java: cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK) $success = openssl_private_decrypt($block, $decryptedBlock, $privateKey, OPENSSL_PKCS1_PADDING); if (!$success) { $error = openssl_error_string(); throw new Exception("第{$i}段解密失败: $error"); } $decrypted .= $decryptedBlock; $i++; $offset = $i * $maxDecryptBlock; echo " 解密第{$i}段: " . strlen($block) . " bytes -> " . strlen($decryptedBlock) . " bytes\n"; } openssl_free_key($privateKey); echo " 总明文长度: " . strlen($decrypted) . " bytes\n\n"; return $decrypted; } // 测试数据 $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='; $plaintext = '{"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商户"}}'; echo "【测试1】PHP加密 + PHP解密(验证代码正确性)\n"; echo "========================================\n"; try { echo "原始明文: " . substr($plaintext, 0, 80) . "...\n\n"; echo "步骤1: 用公钥加密\n"; $encrypted = rsaEncrypt($plaintext, $demoPublicKey); echo "步骤2: 用私钥解密\n"; $decrypted = rsaDecrypt($encrypted, $demoPrivateKey); echo "========================================\n"; echo "解密结果: " . substr($decrypted, 0, 80) . "...\n\n"; echo "验证结果: " . ($decrypted === $plaintext ? "✓ 成功!加密解密完全一致" : "✗ 失败") . "\n\n"; if ($decrypted === $plaintext) { echo "【结论】PHP实现的RSA加密解密代码是正确的!\n\n"; } } catch (Exception $e) { echo "✗ 错误: " . $e->getMessage() . "\n\n"; } echo "\n【测试2】尝试解密Java demo提供的密文\n"; echo "========================================\n"; $demoCiphertext = 'Y2tFMDFJd2RGMGg5aFdXUGtjVVdaSmo4NHBKQzNNZE1wQTRRSXZVRlhBSWhqVEdXNE1LcE9MOXdxY0hhNUlIZndUU0RLK3NrZ1hpTytJUitpREEwSUp0bktRcWMxRG5hN1R0OEtjcUkxTUFDVE5FY2Z0b3lCeTVTaEo3cmNjSnBOUVFsSjRBR2htSzRheEhNb0p6N215eFViK1ZjeGd5WjVTTjJQcHUxQlBnZXJsQXE2Q1lrQ2VuSmZEYUxVSks5RGx2Yk9YWDlDczJiVVllYjlHSHQrUkFuYTljc2hucGhqVWNwNDgrcThNcGhQOElBL20xNVk5NG9lZEV4SXpmc0pDcDExZjFvQ0E5YkwwOWJOZjM4VHR3TkJkTmhqM3lKSVpWeWVpT0FucGhjS3JpOEs5RnlZbXlNVHF1UER3UjhmQ0p5dk5vYkNMS1BPRmQ3WFdXTVczZ29kSWpLaG5OUnhnaFA3N2txdDU3K2Rkd3hGbDgxUEdYbXJWN1ZKWDFOeXRVUFg2dWp3ZzdsUU1OSTlubU1kVE9nbHZJUHRoS205aEludFc2ZFBVTG1DUlNLNzZDc05qTUIyb1hTR2M2cHBNazMxNDJSa05KR0hvY1ZBNFUzcmc4SVk4ZFlYaTUzZmF3cHRES3pHY2JZVFI0SldRVzRNU2ZmSUxvNFpxTkY='; try { echo "demo密文长度: " . strlen($demoCiphertext) . " characters\n\n"; $decrypted = rsaDecrypt($demoCiphertext, $demoPrivateKey); echo "========================================\n"; echo "✓ 解密成功!\n"; echo "解密结果: $decrypted\n\n"; echo "与原始明文对比: " . ($decrypted === $plaintext ? "✓ 完全一致" : "✗ 不一致") . "\n\n"; } catch (Exception $e) { echo "✗ 解密失败: " . $e->getMessage() . "\n\n"; echo "【分析】\n"; echo "1. 如果测试1成功,说明PHP代码是正确的\n"; echo "2. demo密文无法解密可能因为:\n"; echo " - demo密文不是用demo公钥加密的\n"; echo " - demo密文只是格式示例,不是真实密文\n"; echo " - 需要用建行平台公钥加密,而不是demo公钥\n\n"; } echo "========== 测试完成 ==========\n\n";