4

我发布这个是希望它可以节省我在这个涉及转换公钥格式的非常愚蠢的问题上浪费的时间。如果有人看到更简单的解决方案或问题,请告诉我!

我使用的电子商务系统会向我发送一些数据以及签名。他们还以 .pem 格式给我他们的公钥。.pem 文件如下所示:

-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDe+hkicNP7ROHUssGNtHwiT2Ew HFrSk/qwrcq8v5metRtTTFPE/nmzSkRnTs3GMpi57rBdxBBJW5W9cpNyGUh0jNXc VrOSClpD5Ri2hER/GcNrxVRP7RlWOqB1C03q4QYmwjHZ+zlM4OUhCCAtSWflB4wC Ka1g88CjFwRw/PB9kwIDAQAB -----END PUBLIC KEY-----

这是将上述内容转换为能够验证签名的“RSACryptoServiceProvider”的神奇代码。使用 BouncyCastle 库,因为 .NET 显然(如果没有涉及证书文件的一些主要问题,就无法做到这一点):

RSACryptoServiceProvider thingee;

using (var reader = File.OpenText(@"c:\pemfile.pem"))
{
    var x = new PemReader(reader);
    var y = (RsaKeyParameters)x.ReadObject();

    thingee = (RSACryptoServiceProvider)RSACryptoServiceProvider.Create();
    var pa = new RSAParameters();
    pa.Modulus = y.Modulus.ToByteArray();
    pa.Exponent = y.Exponent.ToByteArray();
    thingee.ImportParameters(pa);
}

然后是实际验证签名的代码:

var signature = ... //reads from the packet sent by the eCommerce system
var data = ... //reads from the packet sent by the eCommerce system
var sha = new SHA1CryptoServiceProvider();
byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(data));
byte[] bSignature = Convert.FromBase64String(signature);

///Verify signature, FINALLY:
var hasValidSig = thingee.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), bSignature);
4

1 回答 1

2

潜在问题:使用Encoding.ASCII.GetBytes(data)几乎可以肯定是获取哈希的错误方法。这意味着他们只能发送一个没有设置任何高位的哈希。

如果这是在“数据包”中,您应该从数据包中获取原始数据作为字节数组。如果它表示为文本,它应该是某种编码形式——例如十六进制或base64。哈希是什么样的?

于 2009-06-29T15:10:25.760 回答