非對稱加密RSA的應用及在C#中的實現

quote: http://www.cnblogs.com/happinessCodes/archive/2010/07/27/1786404.htmlhtml

 

    一說到數據的加密,經常會涉及到這幾個單詞:算法、原文、密文和密鑰。一般,發送者把原文經過一個加密的算法,用密鑰進行加密後將密文發送給接收者,而後接收者再用密鑰對密文進行解密,獲得原文。因爲經常使用的加密算法都是公開的,因此,對原文的加密的關鍵,就是密鑰了。對於這種加解密都使用一樣的密鑰的算法,咱們稱之爲對稱加密,對稱加密的表明算法就是DES家族了。那麼這種對稱加密有什麼缺陷呢?因爲加解密使用相同的密鑰,那麼這個密鑰最少要保存在兩個地方,若是加密的數據要發給多人,那麼就會有更多的人知道密鑰,這大大增長了密鑰泄露的風險;而且密鑰須要由發送方傳遞給接收方,那麼如何保證密鑰的傳遞的安全,則成了另一個頭疼的事情。爲了解決這個問題,相對於對稱加密,又出現了非對稱加密。算法

    什麼是非對稱加密?所謂的非對稱加密,就是指加密和解密使用不一樣的密鑰的一類加密算法。這類加密算法一般有兩個密鑰A和B,使用密鑰A加密數據獲得的密文,只有密鑰B能夠進行解密操做(即便密鑰A也沒法解密),相反,使用了密鑰B加密數據獲得的密文,只有密鑰A能夠解密。這兩個密鑰分別稱爲私鑰和公鑰,顧名思義,私鑰就是你我的保留,不能公開的密鑰,而公鑰則是公開給加解密操做的另外一方的。根據不一樣用途,對數據進行加密所使用的密鑰也不相同(有時用公鑰加密,私鑰解密;有時相反用私鑰加密,公鑰解密)。非對稱加密的表明算法是RSA算法。安全

那麼非對稱加密到底有哪些用途?網絡

第一個用途固然是作數據加密。app

    請你們想象一下,若是我不想讓除了接收方之外的其餘人,知道我發送的數據的內容的話,須要用哪一種密鑰對數據進行加密?若是我使用私鑰加密,那麼根據非對稱加密的原理,接收方須要使用公鑰來解密,而公鑰我已經公開給接收方了,這個方案彷佛是可行的,但是這樣作問題就出如今公鑰上了。在非對稱加密中,公鑰的公開不只僅指對接收方的公開,而是指這個密鑰完全的公開,任何人須要均可以獲得,這樣的話你發送的數據就沒有任何祕密可言了。反過來,若是我使用公鑰對數據加密,那麼對於接收方來講就須要使用私鑰進行數據解密,因爲私鑰只保存在接收方手中,這樣其餘人就不會獲得數據的內容了。這樣看來,在非對稱加密中,若是須要保護你的數據不被第三者獲得,密鑰須要由接收方產生,而後接收方將公鑰公開出去,發送方使用這個公開的公鑰對數據進行加密後傳輸給接收方,接收方使用本身的私鑰進行解密,從而保證了數據的安全性。因此非對稱加密又稱爲公鑰加密。ide

    非對稱加密的執行效率要遠低於對稱加密,因此咱們不會對一個大的文件或數據使用非對稱加密算法。那麼咱們如何加密一個大的文件呢?一般狀況咱們能夠選擇對稱加密算法加密文件,而後使用非對稱算法加密對稱算法的密鑰,這樣就保證了對稱算法密鑰傳遞的安全性。函數

非對稱加密的另一個用途就是用來進行數字簽名。post

    什麼是數字簽名?數字簽名同咱們在合同上的簽字同樣,接收方能夠用它來證實收到的數據或文件是由你發送的。舉個例子:假設發送方須要將一串數據D發送給接收方,那麼接收方如何判斷數據D是發送方發送的呢?加密

Step 1:發送方先產生成一對密鑰,並將公鑰公開給接收方;spa

Step 2:發送方將數據D用私鑰進行加密獲得密文M,而後將數據D和密文M一塊兒發送給接收方;

Step 3:接收方獲得數據D和密文M後,用公鑰將密文M解密獲得d;

Step 4:比較D和d,相等則證實D是由發送方發送的。

    在實際的操做中,咱們並不會直接用私鑰去加密要發送的數據或文件,這是由於非對稱加密的算法很是耗時而且密文的長度要大於明文的長度,直接加密系統的開銷很是大。那麼如何實解決這個問題呢?

    首先,咱們須要瞭解另一個概念:消息摘要。所謂的消息摘要就是經過一種單向算法計算出來的惟一對應一個文件或數據的固定長度的值,也被稱做數字摘要。根據不一樣的算法,消息摘要的長度通常爲128位或160位。經常使用的消息摘要的算法有MD5和SHA1。一個文件的消息摘要就同一我的的指紋同樣,它能夠惟一表明這個文件,若是這個文件被修改了,那麼它的消息摘要也必定會發生變化,因此,咱們能夠經過對一個文件的消息摘要進行簽名來代替對它自己進行簽名。而且,咱們還能夠經過驗證消息摘要,來肯定發送的數據是否完整或曾經被修改過。這樣,上面的例子大體能夠變爲下面這樣:

Step 1:發送方先產生成一對密鑰,並將公鑰公開給接收方;

Step 2:發送方將數據D進行消息摘要,獲得Q;

Step 3:用私鑰對Q進行加密獲得密文MQ,而後將數據D和密文MQ一塊兒發送給接收方;

Step 4:接收方獲得數據D和密文MQ後,用公鑰將密文MQ解密獲得q1;

Step 5:接收方使用相同的算法對數據D進行消息摘要,獲得q2;

Step 6:比較q1和q2,相等則證實D是由發送方發送的,且沒有被修改過。

    好了,非對稱加密的使用介紹了一大堆,後面咱們來看看如何用C#來實現RSA非對稱加密。

    .Net中的加密操做所涉及的對象都在命名空間System.Security.Cryptography下,因此請先在你的程序中添加using System.Security.Cryptography; 其中,RSA加密算法由RSACryptoServiceProvider對象實現。下面的代碼分別實現了數據的加密解密和簽名與驗證。

 1             string PublicKey, PrivateKey;
 2             RSACryptoServiceProvider rsaProvider;
 3 
 4             void Initial()
 5             {
 6                 //聲明一個RSA算法的實例,由RSACryptoServiceProvider類型的構造函數指定了密鑰長度爲1024位
 7                 //實例化RSACryptoServiceProvider後,RSACryptoServiceProvider會自動生成密鑰信息。
 8                 rsaProvider = new RSACryptoServiceProvider(1024);
 9                 //將RSA算法的公鑰導出到字符串PublicKey中,參數爲false表示不導出私鑰
10                 PublicKey = rsaProvider.ToXmlString(false);
11                 //將RSA算法的私鑰導出到字符串PrivateKey中,參數爲true表示導出私鑰
12                 PrivateKey = rsaProvider.ToXmlString(true);
13             }
14 
15             byte[] EncryptData(byte[] data)
16             {
17                 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
18                 //將公鑰導入到RSA對象中,準備加密;
19                 rsa.FromXmlString(PublicKey);
20                 //對數據data進行加密,並返回加密結果;
21                 //第二個參數用來選擇Padding的格式
22                 return rsa.Encrypt(data, false);
23             }
24 
25             byte[] DecryptData(byte[] data)
26             {
27                 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
28                 //將私鑰導入RSA中,準備解密;
29                 rsa.FromXmlString(PrivateKey);
30                 //對數據進行解密,並返回解密結果;
31                 return rsa.Decrypt(data, false);
32             }
33 
34             byte[] Sign(byte[] data)
35             {
36                 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
37                 //導入私鑰,準備簽名
38                 rsa.FromXmlString(PrivateKey);
39                 //將數據使用MD5進行消息摘要,而後對摘要進行簽名並返回簽名數據
40                 return rsa.SignData(data, "MD5");
41             }
42 
43             bool Verify(byte[] data, byte[] Signature)
44             {
45                 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
46                 //導入公鑰,準備驗證簽名
47                 rsa.FromXmlString(PublicKey);
48                 //返回數據驗證結果
49                 return rsa.VerifyData(data, "MD5", Signature);
50             }

關於RSA更多的內容,你們能夠參照MSDN和網絡上的教程本身動手進行練習。我會在後面的文章中繼續講解關於密鑰的保存方面的內容,但願你們喜歡。

另外但願你們到網上查查RSA的具體算法,很是有意思,而且很是佩服設計出這些算法的人,真不知道他們的腦殼裏裝的都是什麼~~

相關文章
相關標籤/搜索