{"agetId":"61000000103774","pdata":"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"}
{"ACCOUNT_NAME":"王玉茹","ACCOUNT_NO":"6215699120","AGE_CUST_ID":"61000000103774","AGE_NAME":"郑秀华收单01一级","AUTH_DATE":"2025-11-08 17:07:10","AUTH_RESULT":"00","AUTH_TYPE":"0","BANK_NAME":"BOC","BUS_NAME":"福建合码通信息服务有限责任公司","CUST_ID":"60000001056036","CUST_TYPE":"1","IND_TYPE":"计算机软件开发、系统集成、数据处理服务,7372","IS_SIGNAXQ":"0","MERGER_ID":"","MERGER_NAME":"","MERGER_PH":"","NOT_THROW_REASON":"","PHONE":"1378372","THIRD_NO":"85735017372U03H","sign":"nxz/UodhiAIPrBkoc3QWGeFMe6YjNrFiwtrjCZ9Dp1gtWMZs9fAOk+IwrVReSDS+SIW44UU/5/VX6PmTfIooXghiYx40zhPwbMDEmDWkSZ0SW1h9VzE+uZfi8gMJGy35NYQvl9O0ShYVBw2hnEUyD9JGd+TlGOHsZ6eRgYXlDguepceN9JV4OuMKM7jDP/wFUNuB292S0rM1MtolJmjrfNTgvxwTvRu1ykz+L/QLpM5N0PJnGmpPOkV0ij4/UALGArH+yV2YOgPekzFbP0WZJyY4LI/fSVPN8/Qk7W0wu5dzsVAnRNWNyAq4kAECRzABOZRlrKVJLeimwL2PmKr7Rw=="}
ACCOUNT_NAME=王玉茹&ACCOUNT_NO=6215699120&AGE_CUST_ID=61000000103774&AGE_NAME=郑秀华收单01一级&AUTH_DATE=2025-11-08 17:07:10&AUTH_RESULT=00&AUTH_TYPE=0&BANK_NAME=BOC&BUS_NAME=福建合码通信息服务有限责任公司&CUST_ID=60000001056036&CUST_TYPE=1&IND_TYPE=计算机软件开发、系统集成、数据处理服务,7372&IS_SIGNAXQ=0&MERGER_ID=&MERGER_NAME=&MERGER_PH=&NOT_THROW_REASON=&PHONE=1378372&THIRD_NO=85735017372U03H
94af9639c04c9343d1f8627950baece652274722c4377f62e201e73c7e6fef67
using Newtonsoft.Json;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace Api.XYFPay.Helper.Test
{
public class RSA2Helper
{
private static string pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhWb4rG/iWIxLVM9u7LtAWWliOpLUG4gat7t1DACtwsdxIrxG2eIRvVyol6lMnulGE6kx7c2P9AiJZTcZ4iQjK1BTj0s4IhpPgGibF0xo6mesvw/1IyTQs02c+gCcy3C7qJgIVF4IhF7DA4RhHJ/wUixTITdbpw2JIVw+VRiEAPXOOi6uIOlvKflDWQW8AP/bYRWISxgb6finKhbMGNJgeUh/QAtsPOvocRVTCd/OvmSCcP8y+Qck8qbdJdgHOSuCNontHsa3TBHzJASkwJSnRmkdRuNq+fFgPMqItj9p0wu7KcI0wm+Llk5R+xeYdLOspmf4JMNh+XX7zP/B2AARgQIDAQAB";
static void Main(string[] args)
{
try
{
var notifyBody = "{\"agetId\":\"61000000583951\",\"pdata\":\"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\"}";
var parameters = JsonConvert.DeserializeObject<Dictionary<string, object>>(notifyBody);
if (parameters == null || !parameters.TryGetValue("pdata", out object pdataObj))
throw new Exception("未找到 pdata 字段");
string pdata = pdataObj.ToString();
// 分段解密 pdata(整个 JSON 密文)
byte[] plainBytes = DecryptByPublicKey(pdata, pubKey);
string plainTextStr = Encoding.UTF8.GetString(plainBytes);
Console.WriteLine("解密后的 JSON 明文: " + plainTextStr);
var plainText = JsonConvert.DeserializeObject<Dictionary<string, object>>(plainTextStr);
if (plainText == null || !plainText.TryGetValue("sign", out object signObj))
throw new Exception("pdata 中未找到 sign 字段");
string sign = signObj.ToString();
plainText.Remove("sign");
// 按字典序排序并拼接
var sortedParams = plainText.OrderBy(p => p.Key, StringComparer.Ordinal)
.Select(p => $"{p.Key}={p.Value}");
string parameterString = string.Join("&", sortedParams);
Console.WriteLine("待签名字符串: " + parameterString);
// 计算本地 SHA256 (十六进制)
string localSha256Hex = SHA256Encrypt(parameterString);
Console.WriteLine("本地 SHA256: " + localSha256Hex);
// 解密 sign
byte[] signDecryptedBytes = DecryptByPublicKey(sign, pubKey);
string signSha256Hex = Encoding.UTF8.GetString(signDecryptedBytes);
Console.WriteLine("sign解密: " + signSha256Hex);
// 比较
if (signSha256Hex == localSha256Hex)
Console.WriteLine("验签通过");
else
Console.WriteLine("验签失败");
}
catch (Exception ex)
{
Console.WriteLine($"异常: {ex.Message}");
Console.WriteLine(ex.StackTrace);
}
}
/// <summary>
/// 分段 RSA 公钥解密
/// </summary>
public static byte[] DecryptByPublicKey(string data, string publicKey)
{
byte[] encryptedData = Convert.FromBase64String(data);
string xmlPublicKey = RSAPublicKeyJava2DotNet(publicKey);
using (var rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(xmlPublicKey);
int keySizeBytes = rsa.KeySize / 8; // 2048 位 → 256 字节
// 检查长度是否为 keySizeBytes 的整数倍
if (encryptedData.Length % keySizeBytes != 0)
throw new Exception($"密文长度 {encryptedData.Length} 不是 {keySizeBytes} 的整数倍,可能密钥不匹配或数据损坏。");
// 初始化 BouncyCastle 解密器
var keyParam = DotNetUtilities.GetRsaPublicKey(rsa);
IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
cipher.Init(false, keyParam);
using (var outStream = new MemoryStream())
{
int offset = 0;
while (offset < encryptedData.Length)
{
byte[] block = new byte[keySizeBytes];
Array.Copy(encryptedData, offset, block, 0, keySizeBytes);
byte[] decryptedBlock = cipher.DoFinal(block);
outStream.Write(decryptedBlock, 0, decryptedBlock.Length);
offset += keySizeBytes;
}
return outStream.ToArray();
}
}
}
/// <summary>
/// Java RSA 公钥格式转 .NET 格式
/// </summary>
private static string RSAPublicKeyJava2DotNet(string publicKey)
{
var publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
}
/// <summary>
/// SHA256 哈希(返回小写十六进制)
/// </summary>
public static string SHA256Encrypt(string data)
{
using (var sha256 = SHA256.Create())
{
byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(data));
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
}
}
}const crypto = require('crypto');
function decryptByPublicKey(ciphertext, publicKeyBase64, blockSize) {
const pubKey = crypto.createPublicKey({
key: Buffer.from(publicKeyBase64, 'base64'),
format: 'der',
type: 'spki'
});
if (ciphertext.length % blockSize !== 0) {
throw new Error(`密文长度 ${ciphertext.length} 不是 ${blockSize} 的整数倍`);
}
const parts = [];
for (let offset = 0; offset < ciphertext.length; offset += blockSize) {
const block = ciphertext.slice(offset, offset + blockSize);
let decrypted;
try {
decrypted = crypto.publicDecrypt(
{ key: pubKey, padding: crypto.constants.RSA_PKCS1_PADDING },
block
);
} catch (err) {
console.error(`块 ${offset/blockSize} 解密失败:`, err.message);
throw err;
}
parts.push(decrypted);
}
return Buffer.concat(parts);
}
function verifySign(jsonStr, publicKeyBase64) {
const data = JSON.parse(jsonStr);
const pdata = data.pdata;
const ciphertext = Buffer.from(pdata, 'base64');
// 自动推断块大小:从公钥获取模长,若获取不到则尝试 256
let blockSize = 256;
let decryptedStr;
try {
const plainBuffer = decryptByPublicKey(ciphertext, publicKeyBase64, blockSize);
decryptedStr = plainBuffer.toString('utf8');
} catch (err) {
throw new Error(`解密 pdata 失败: ${err.message}`);
}
console.log('解密pdata:', decryptedStr);
const inner = JSON.parse(decryptedStr);
const signBase64 = inner.sign;
delete inner.sign;
const keys = Object.keys(inner).sort();
const parts = keys.map(k => `${k}=${typeof inner[k] === 'object' ? JSON.stringify(inner[k]) : String(inner[k])}`);
const signedStr = parts.join('&');
console.log('拼接串:', signedStr);
const hash = crypto.createHash('sha256').update(signedStr, 'utf8').digest('hex');
console.log('本地SHA256:', hash);
const signCipher = Buffer.from(signBase64, 'base64');
const signPlain = decryptByPublicKey(signCipher, publicKeyBase64, blockSize);
const signHex = signPlain.toString('utf8');
console.log('sign解密:', signHex);
return hash === signHex;
}
// 使用
const notifyBody = `{"agetId":"61000000583951","pdata":"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"}`;
const publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhWb4rG/iWIxLVM9u7LtAWWliOpLUG4gat7t1DACtwsdxIrxG2eIRvVyol6lMnulGE6kx7c2P9AiJZTcZ4iQjK1BTj0s4IhpPgGibF0xo6mesvw/1IyTQs02c+gCcy3C7qJgIVF4IhF7DA4RhHJ/wUixTITdbpw2JIVw+VRiEAPXOOi6uIOlvKflDWQW8AP/bYRWISxgb6finKhbMGNJgeUh/QAtsPOvocRVTCd/OvmSCcP8y+Qck8qbdJdgHOSuCNontHsa3TBHzJASkwJSnRmkdRuNq+fFgPMqItj9p0wu7KcI0wm+Llk5R+xeYdLOspmf4JMNh+XX7zP/B2AARgQIDAQAB";
try {
const ok = verifySign(notifyBody, publicKeyBase64);
console.log(ok ? '验签通过' : '验签失败');
} catch (err) {
console.error('验签出错:', err.message);
}{
"rspCod": "000000",
"rspMsg": "success"
}