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