我发布此信息是希望它可以节省其他人在这个涉及转换公钥格式这个非常愚蠢的问题上丢失的时间。如果有人看到更简单的解决方案或问题,请告诉我!
我正在使用的电子商务系统向我发送了一些数据以及签名。他们还以.pem格式给我他们的公钥。 .pem文件如下所示:
-----开始公钥----- 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);
答案 0 :(得分:2)
潜在问题:使用Encoding.ASCII.GetBytes(data)
几乎肯定是获取哈希的错误方法。这意味着他们只能 发送一个没有设置任何高位的哈希值。
如果这是一个“数据包”,你应该从数据包中获取原始数据作为字节数组。如果 表示为文本,则它应采用某种编码形式 - 例如十六进制或base64。哈希是什么样的?