我发布这个是希望它可以节省我在这个涉及转换公钥格式的非常愚蠢的问题上浪费的时间。如果有人看到更简单的解决方案或问题,请告诉我!
我使用的电子商务系统会向我发送一些数据以及签名。他们还以 .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);