25

我回顾了很多论坛和例子,但没有人帮助我。我需要从任何Web服务验证签名。我使用公钥验证test.crt文件。如何验证签名,从CRT文件加载PUBLIC KEY?

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 
+0

我创建了一个简单的应用程序,生成一个文本签名,并立即对其进行验证。你可以在这里查看:https://dl.dropbox.com/u/1171045/11221877/Program.cs –

+0

所以上面的方法相当好。您确定您使用正确的证书进行签名和验证吗? –

+3

我对网络应用也做了同样的事情,所以它不是网络。你如何将签名从Web服务传递到你的应用程序? –

回答

1

我怀疑使用UnicodeEncoding可能是失败的原因,作为证明ASCIIEncoding的字节下方和UnicodeEncoding是不一样的,因为ASCII是8位编码,在Windows中,Unicode编码是16位宽。在你的其他问题Can not get signature中,你已经使用了ASCIIEncoding,所以假设签名是在文本/字符串的ASCIIE编码字节和v使用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