如何验证签名,从CRT文件加载PUBLIC KEY?

时间:2012-06-27 08:06:39

标签: c# cryptography digital-signature public-key-encryption x509

我查看了许多论坛和示例,但没有人帮助过我。我需要从任何Web服务验证签名。我有test.crt文件,带有用于验证的公钥。

static bool Verify(string text, string signature)
{
  X509Certificate2 cert = new X509Certificate2(
      HttpContext.Current.Server.MapPath("test-server.cert"));
  RSACryptoServiceProvider csp = (RSACryptoServiceProvider) cert.PublicKey.Key;

  // Hash the data
  SHA1Managed sha1 = new SHA1Managed();
  UnicodeEncoding encoding = new UnicodeEncoding();
  byte[] data = encoding.GetBytes(text);
  byte[] sign = Convert.FromBase64String(signature);
  byte[] hash = sha1.ComputeHash(data);

  return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), sign);
}

但结果总是错误的:(

我有一个OpenSSL示例:

openssl base64 -d -in signature -out signature.bin
openssl dgst -sha1 -verify test-server.pub -signature signature.bin from_gateway

1 个答案:

答案 0 :(得分:1)

我怀疑使用UnicodeEncoding可能是失败的原因。如下所示,ASCIIEncoding和UnicodeEncoding的字节不相同,因为ASCII是8位编码,而Windows Unicode编码是16位宽。在您的另一个问题Can not get signature中,您使用了ASCIIEncoding。假设签名是在文本/字符串的ASCIIEncoding字节上计算的,并且使用UnicodeEncoding进行验证显然不匹配。

string text = "Hello";
Console.WriteLine("ASCIIEncoding bytes length: {0}", new ASCIIEncoding().GetBytes(text).Length);
Console.WriteLine("UnicodeEncoding bytes length: {0}", new UnicodeEncoding().GetBytes(text).Length);

输出

ASCIIEncoding bytes length: 5
UnicodeEncoding bytes length: 10