Python生成RSA签名后C#端验证始终失败问题求助
问题根因
你遇到的是BouncyCastle的BigInteger类型与.NET的RSAParameters对字节序/符号位处理不一致的问题:
- BouncyCastle的
BigInteger.ToByteArray()返回的是带符号的大端字节数组,如果模数(Modulus)的最高位为1,会自动在头部追加一个0x00字节来标识这是正数 - .NET的
RSAParameters要求Modulus、Exponent必须是无符号的大端字节数组,不需要前导的符号位字节,多余的前导0x00会导致公钥参数导入错误,最终验证失败
修复方案
修改C#代码中导入公钥参数的逻辑,移除Modulus前多余的前导0x00字节即可:
private void button_Click(object sender, EventArgs e) { byte[] data = File.ReadAllBytes("message.dat"); byte[] signature = File.ReadAllBytes("signed.dat"); try { using (var reader = File.OpenText("id_rsa.pub")) { var pem = new PemReader(reader); var o = (RsaKeyParameters)pem.ReadObject(); using (var rsa = new RSACryptoServiceProvider()) { var parameters = new RSAParameters(); // 处理Modulus:移除前导的0x00符号字节 byte[] modulusBytes = o.Modulus.ToByteArray(); if (modulusBytes[0] == 0x00) { parameters.Modulus = modulusBytes.Skip(1).ToArray(); } else { parameters.Modulus = modulusBytes; } parameters.Exponent = o.Exponent.ToByteArray(); rsa.ImportParameters(parameters); bool ok = rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); if (ok) Console.WriteLine("Verified"); } } } catch (CryptographicException exc) { Console.WriteLine(exc.Message); } }
额外排查点
如果修改后仍然验证失败,可以按顺序排查:
- 确认两边使用的哈希算法完全一致,都是SHA256+PKCS1v15填充
- 确认读取的message.dat、signed.dat文件没有被额外编码/转换,都是原始二进制读取
- 确认公钥文件是和Python签名用的私钥配对的RSA公钥
内容的提问来源于stack exchange,提问作者Tumbelo
相关产品推荐
相关产品推荐

