2011-07-17 70 views
1

使用BouncyCastle的,並幫助從計算器問題,我得到這個(簽署了RSA私鑰):C#驗證數據與公開密鑰

 using System.Net.Sockets; 
     using System.Security.Cryptography; 
     using Org.BouncyCastle.Crypto.Parameters; 
     using Org.BouncyCastle.OpenSsl; 

...

 TcpClient client = new TcpClient("127.0.0.1", 1337); 
     NetworkStream stream = client.GetStream(); 

     StreamWriter writer= new StreamWriter(stream); 
     StreamReader reader = new StreamReader(stream); 

     writer.WriteLine("hello"); 
     writer.AutoFlush = true; 

     string response = Convert.FromBase64String(reader.ReadToEnd()).ToString(); 

     RSACryptoServiceProvider RCP; 
     var x = new PemReader(File.OpenText(pubkey)); 
     var y = (RsaKeyParameters)x.ReadObject(); 

     RCP = (RSACryptoServiceProvider)RSACryptoServiceProvider.Create(); 

     var pa = new RSAParameters(); 
     pa.Modulus = y.Modulus.ToByteArray(); 
     pa.Exponent = y.Exponent.ToByteArray(); 

     RCP.ImportParameters(pa); 
     byte[] test = RCP.Decrypt(response, true); 

現在,很明顯解密將會失敗,因爲我試圖解密已簽名的東西(不是「加密」),而且肯定不是由相同的「密鑰」解密。我很困惑,因爲我認爲我應該使用像VerifyData()這樣的方法,但是這會返回一個布爾值,並且我不確定我有沒有參數。

我希望完成的是C#相當於openssl rsautl -verify -inkey public.pem -pubin。也就是說,用pubkey「解密」來驗證所述消息的內容。

我在正確的軌道上嗎?

  • Mik的
+0

儘管爲了我的目的,我可能已經進行了驗證,並且不需要解密,但我確實將其用於其他目的。比起Bouncycastle更簡單的解決方案(至少對我來說)是這樣的:'OpenSSL.Core.BIO bin = new OpenSSL.Core.BIO(public_key_as_string); OpenSSL.Crypto.RSA rsa = OpenSSL.Crypto.RSA.FromPublicKey(bin,null,null); byte [] message = new byte [1024]; message = rsa.PublicDecrypt(base64string,OpenSSL.Crypto.RSA.Padding.PKCS1);'使用託管的[OpenSSL.NET](http://openssl-net.sourceforge.net/)包裝器。 – Mik

回答

0

事實上,除非你指定了錯誤的編碼參數的簽名的解密應該永遠不會失敗 - 簽名是簡單的數據(通常是SHA1)的私有密鑰加密散​​列;使用驗證例程的唯一好處是它可以解密塊併爲你進行散列比較,如果你想成爲血腥頭腦的人,你可以用你的公鑰進行解密操作,並自己比較散列字節。

我真的不確定response是什麼在您的程序的上下文中;你應該只有被傳遞給它的RSA數據,如果你也給它提供的數據是第一個簽名的地方你是做錯了 - 同樣,請檢查該函數是否實際接受一個字符串,in我的經驗BouncyCastle的普遍預計一byte[]

我推薦使用SignerUtilities.GetSigner() - 它需要一個字符串參數告訴它你使用什麼樣的簽名,我會想象"SHA1WithRSA"是適合你的。