RSA加密的使用


一、知識點

對稱加密的代表DES加密
缺陷:
  1、由於加解密使用相同的密鑰,那么這個密鑰最少要保存在兩個地方,如果加密的數據要發給多人,那么就會有更多的人知道密鑰,這大大增加了密鑰泄露的風險
  2、密鑰需要由發送方傳遞給接收方,如何保證傳遞安全

 

非對稱加密,就是指加密和解密使用不同的密鑰的一類加密算法
這類加密算法通常有兩個密鑰A和B,使用密鑰A加密數據得到的密文,只有密鑰B可以進行解密操作(即使密鑰A也無法解密),相反,使用了密鑰B加密數據得到的密文,只有密鑰A可以解密。
這兩個密鑰分別稱為私鑰和公鑰,顧名思義,私鑰就是你個人保留,不能公開的密鑰,而公鑰則是公開給加解密操作的另一方的。
用途:
  1、數據加密。在非對稱加密中,公鑰的公開不僅僅指對接收方的公開,而是指這個密鑰徹底的公開,所以使用的時候應該由接收方保存私鑰,傳遞的數據使用公鑰進行加密,由接收方使用私鑰進行解密。
  2、用來進行數字簽名。使用消息摘要進行數字簽名
    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是由發送方發送的,且沒有被修改過。
缺陷:
  1、非對稱加密的算法非常耗時並且密文的長度要大於明文的長度,直接加密系統的開銷非常大
  2、RSA無法對超過117字節的數據進行加密


消息摘要。
所謂的消息摘要就是通過一種單向算法計算出來的唯一對應一個文件或數據的固定長度的值,也被稱作數字摘要。根據不同的算法,消息摘要的長度一般為128位或160位。常用的消息摘要的算法有MD5和SHA1。
我們可以通過對一個文件的消息摘要進行簽名來代替對它本身進行簽名。並且,我們還可以通過驗證消息摘要,來確定發送的數據是否完整或曾經被修改過。

 

二、RSA相關封裝代碼

 1 using System;  2 using System.Security.Cryptography;  3 using System.Text;  4 
 5 namespace Util  6 {  7     /// <summary>
 8     /// RSA加密解密及RSA簽名和驗證  9     /// </summary>
 10     public static class RSACryption  11  {  12 
 13         #region RSA 加密解密
 14 
 15         /// <summary>
 16         /// RSA 的密鑰產生 產生私鑰 和公鑰  17         /// </summary>
 18         /// <param name="xmlPriKeys">私鑰</param>
 19         /// <param name="xmlPubKeys">公鑰</param>
 20         public static void RSAKey(out string xmlPriKeys, out string xmlPubKeys)  21  {  22             System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();  23 
 24             xmlPriKeys = rsa.ToXmlString(true);    //將密鑰導出為一個xml格式的string,true導出私鑰,false不導出
 25             xmlPubKeys = rsa.ToXmlString(false);  26  }  27 
 28 
 29         #region RSA的加密函數
 30         /// <summary>
 31         /// 對string類型的數據進行RSA的加密函數,該加密方式有 長度 限制的!!  32         /// </summary>
 33         /// <param name="xmlPublicKey">XML的形式的公鑰</param>
 34         /// <param name="m_strEncryptString">私鑰</param>
 35         /// <returns>string類型的加密結果</returns>
 36         public static string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)  37  {  38             byte[] PlainTextBArray;  39             byte[] CypherTextBArray;  40             string Result;  41 
 42             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();  43  rsa.FromXmlString(xmlPublicKey);  44 
 45             PlainTextBArray = (new UnicodeEncoding()).GetBytes(m_strEncryptString);  46             CypherTextBArray = rsa.Encrypt(PlainTextBArray, false);  47 
 48             Result = Convert.ToBase64String(CypherTextBArray);  49             return Result;  50 
 51  }  52 
 53 
 54         /// <summary>
 55         /// 對byte類型數組進行加密,該加密方式有 長度 限制的!!  56         /// </summary>
 57         /// <param name="xmlPublicKey">XML的形式的公鑰</param>
 58         /// <param name="EncryptString">需要加密的byte類型的數組</param>
 59         /// <returns>string類型的加密結果</returns>
 60         public static string RSAEncrypt(string xmlPublicKey, byte[] EncryptString)  61  {  62 
 63             byte[] CypherTextBArray;  64             string Result;  65 
 66             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();  67  rsa.FromXmlString(xmlPublicKey);  68 
 69             CypherTextBArray = rsa.Encrypt(EncryptString, false);  70 
 71             Result = Convert.ToBase64String(CypherTextBArray);  72             return Result;  73 
 74  }  75         #endregion
 76 
 77 
 78         #region RSA的解密函數
 79         /// <summary>
 80         /// RSA的解密函數  81         /// </summary>
 82         /// <param name="xmlPrivateKey">xml類型的私鑰</param>
 83         /// <param name="m_strDecryptString">string類型的密文</param>
 84         /// <returns></returns>
 85         public static string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)  86  {  87             byte[] PlainTextBArray;  88             byte[] DypherTextBArray;  89             string Result;  90             System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();  91  rsa.FromXmlString(xmlPrivateKey);  92             PlainTextBArray = Convert.FromBase64String(m_strDecryptString);  93             DypherTextBArray = rsa.Decrypt(PlainTextBArray, false);  94             Result = (new UnicodeEncoding()).GetString(DypherTextBArray);  95             return Result;  96 
 97  }  98 
 99 
100         /// <summary>
101         /// RSA的解密函數 102         /// </summary>
103         /// <param name="xmlPrivateKey">xml類型的私鑰</param>
104         /// <param name="DecryptString">byte類型數組的密文</param>
105         /// <returns></returns>
106         public static string RSADecrypt(string xmlPrivateKey, byte[] DecryptString) 107  { 108             byte[] DypherTextBArray; 109             string Result; 110             System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 111  rsa.FromXmlString(xmlPrivateKey); 112             DypherTextBArray = rsa.Decrypt(DecryptString, false); 113             Result = (new UnicodeEncoding()).GetString(DypherTextBArray); 114             return Result; 115 
116  } 117         #endregion
118 
119 
120         #endregion
121 
122 
123 
124         #region RSA數字簽名
125 
126         #region 獲取Hash描述表
127 
128         //獲取Hash描述表
129         public static bool GetHash(string m_strSource, ref byte[] HashData) 130  { 131             //從字符串中取得Hash描述
132             byte[] Buffer; 133             System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5"); 134             Buffer = System.Text.Encoding.GetEncoding("GB2312").GetBytes(m_strSource); 135             HashData = MD5.ComputeHash(Buffer); 136 
137             return true; 138  } 139 
140         //獲取Hash描述表
141         public static bool GetHash(string m_strSource, ref string strHashData) 142  { 143             //從字符串中取得Hash描述
144             byte[] Buffer; 145             byte[] HashData; 146             System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5"); 147             Buffer = System.Text.Encoding.GetEncoding("GB2312").GetBytes(m_strSource); 148             HashData = MD5.ComputeHash(Buffer); 149 
150             strHashData = Convert.ToBase64String(HashData); 151             return true; 152  } 153 
154         //獲取Hash描述表
155         public static bool GetHash(System.IO.FileStream objFile, ref byte[] HashData) 156  { 157             //從文件中取得Hash描述
158             System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5"); 159             HashData = MD5.ComputeHash(objFile); 160  objFile.Close(); 161 
162             return true; 163  } 164 
165         //獲取Hash描述表
166         public static bool GetHash(System.IO.FileStream objFile, ref string strHashData) 167  { 168             //從文件中取得Hash描述
169             byte[] HashData; 170             System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.HashAlgorithm.Create("MD5"); 171             HashData = MD5.ComputeHash(objFile); 172  objFile.Close(); 173 
174             strHashData = Convert.ToBase64String(HashData); 175 
176             return true; 177  } 178 
179         #endregion
180 
181 
182 
183         #region RSA簽名
184         /// <summary>
185         /// RSA簽名 186         /// </summary>
187         /// <param name="p_strKeyPrivate"></param>
188         /// <param name="HashbyteSignature"></param>
189         /// <param name="EncryptedSignatureData"></param>
190         /// <returns></returns>
191         public static bool SignatureFormatter(string p_strKeyPrivate, byte[] HashbyteSignature, ref byte[] EncryptedSignatureData) 192  { 193             System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); 194 
195  RSA.FromXmlString(p_strKeyPrivate); 196             System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA); 197             //設置簽名的算法為MD5
198             RSAFormatter.SetHashAlgorithm("MD5"); 199             //執行簽名
200             EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature); 201 
202             return true; 203 
204  } 205 
206         /// <summary>
207         /// RSA簽名 208         /// </summary>
209         /// <param name="p_strKeyPrivate"></param>
210         /// <param name="HashbyteSignature"></param>
211         /// <param name="m_strEncryptedSignatureData"></param>
212         /// <returns></returns>
213         public static bool SignatureFormatter(string p_strKeyPrivate, byte[] HashbyteSignature, ref string m_strEncryptedSignatureData) 214  { 215 
216             byte[] EncryptedSignatureData; 217 
218             System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); 219 
220  RSA.FromXmlString(p_strKeyPrivate); 221             System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA); 222             //設置簽名的算法為MD5
223             RSAFormatter.SetHashAlgorithm("MD5"); 224             //執行簽名
225             EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature); 226 
227             m_strEncryptedSignatureData = Convert.ToBase64String(EncryptedSignatureData); 228 
229             return true; 230 
231  } 232 
233         /// <summary>
234         /// RSA簽名 235         /// </summary>
236         /// <param name="p_strKeyPrivate"></param>
237         /// <param name="m_strHashbyteSignature"></param>
238         /// <param name="EncryptedSignatureData"></param>
239         /// <returns></returns>
240         public static bool SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature, ref byte[] EncryptedSignatureData) 241  { 242 
243             byte[] HashbyteSignature; 244 
245             HashbyteSignature = Convert.FromBase64String(m_strHashbyteSignature); 246             System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); 247 
248  RSA.FromXmlString(p_strKeyPrivate); 249             System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA); 250             //設置簽名的算法為MD5
251             RSAFormatter.SetHashAlgorithm("MD5"); 252             //執行簽名
253             EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature); 254 
255             return true; 256 
257  } 258 
259         /// <summary>
260         /// RSA簽名 261         /// </summary>
262         /// <param name="p_strKeyPrivate"></param>
263         /// <param name="m_strHashbyteSignature"></param>
264         /// <param name="m_strEncryptedSignatureData"></param>
265         /// <returns></returns>
266         public static bool SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature, ref string m_strEncryptedSignatureData) 267  { 268 
269             byte[] HashbyteSignature; 270             byte[] EncryptedSignatureData; 271 
272             HashbyteSignature = Convert.FromBase64String(m_strHashbyteSignature); 273             System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); 274 
275  RSA.FromXmlString(p_strKeyPrivate); 276             System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA); 277             //設置簽名的算法為MD5
278             RSAFormatter.SetHashAlgorithm("MD5"); 279             //執行簽名
280             EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature); 281 
282             m_strEncryptedSignatureData = Convert.ToBase64String(EncryptedSignatureData); 283 
284             return true; 285 
286  } 287         #endregion
288 
289 
290 
291         #region RSA 簽名驗證
292 
293         /// <summary>
294         /// RSA 簽名驗證 295         /// </summary>
296         /// <param name="p_strKeyPublic"></param>
297         /// <param name="HashbyteDeformatter"></param>
298         /// <param name="DeformatterData"></param>
299         /// <returns></returns>
300         public static bool SignatureDeformatter(string p_strKeyPublic, byte[] HashbyteDeformatter, byte[] DeformatterData) 301  { 302 
303             System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); 304 
305  RSA.FromXmlString(p_strKeyPublic); 306             System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA); 307             //指定解密的時候HASH算法為MD5
308             RSADeformatter.SetHashAlgorithm("MD5"); 309 
310             if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData)) 311  { 312                 return true; 313  } 314             else
315  { 316                 return false; 317  } 318 
319  } 320 
321         /// <summary>
322         /// RSA 簽名驗證 323         /// </summary>
324         /// <param name="p_strKeyPublic"></param>
325         /// <param name="p_strHashbyteDeformatter"></param>
326         /// <param name="DeformatterData"></param>
327         /// <returns></returns>
328         public static bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, byte[] DeformatterData) 329  { 330 
331             byte[] HashbyteDeformatter; 332 
333             HashbyteDeformatter = Convert.FromBase64String(p_strHashbyteDeformatter); 334 
335             System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); 336 
337  RSA.FromXmlString(p_strKeyPublic); 338             System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA); 339             //指定解密的時候HASH算法為MD5
340             RSADeformatter.SetHashAlgorithm("MD5"); 341 
342             if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData)) 343  { 344                 return true; 345  } 346             else
347  { 348                 return false; 349  } 350 
351  } 352 
353 
354         /// <summary>
355         /// RSA 簽名驗證 356         /// </summary>
357         /// <param name="p_strKeyPublic"></param>
358         /// <param name="HashbyteDeformatter"></param>
359         /// <param name="p_strDeformatterData"></param>
360         /// <returns></returns>
361         public static bool SignatureDeformatter(string p_strKeyPublic, byte[] HashbyteDeformatter, string p_strDeformatterData) 362  { 363 
364             byte[] DeformatterData; 365 
366             System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); 367 
368  RSA.FromXmlString(p_strKeyPublic); 369             System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA); 370             //指定解密的時候HASH算法為MD5
371             RSADeformatter.SetHashAlgorithm("MD5"); 372 
373             DeformatterData = Convert.FromBase64String(p_strDeformatterData); 374 
375             if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData)) 376  { 377                 return true; 378  } 379             else
380  { 381                 return false; 382  } 383 
384  } 385 
386 
387         /// <summary>
388         /// RSA 簽名驗證 389         /// </summary>
390         /// <param name="p_strKeyPublic"></param>
391         /// <param name="p_strHashbyteDeformatter"></param>
392         /// <param name="p_strDeformatterData"></param>
393         /// <returns></returns>
394         public static bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData) 395  { 396 
397             byte[] DeformatterData; 398             byte[] HashbyteDeformatter; 399 
400             HashbyteDeformatter = Convert.FromBase64String(p_strHashbyteDeformatter); 401             System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider(); 402 
403  RSA.FromXmlString(p_strKeyPublic); 404             System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA); 405             //指定解密的時候HASH算法為MD5
406             RSADeformatter.SetHashAlgorithm("MD5"); 407 
408             DeformatterData = Convert.FromBase64String(p_strDeformatterData); 409 
410             if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData)) 411  { 412                 return true; 413  } 414             else
415  { 416                 return false; 417  } 418 
419  } 420 
421 
422         #endregion
423 
424 
425         #endregion
426 
427  } 428 }
View Code

 

三、RSAKey首先提出了需要生成對應的公鑰和私鑰,那么就涉及到保存,對應的保存的三種方法

1.將密鑰導出保存為本地文件(出於安全性考慮,不建議使用這種方法保存私鑰,如果使用,請在密鑰導出的時候只導出公鑰

RSACryptoServiceProvider對象提供了一個ToXmlString(bool includePrivateParameters)方法,我們可以使用此方法將密鑰導出為一個xml格式的string,然后將其保存到一個文件中,這個方法的參數為true時會導出私鑰,否則不導出私鑰。需要的時候,我們可以使用FromXmlString(string xmlString)方法,將保存的密鑰信息加載到RSACryptoServiceProvider對象中。

 1 /// <summary>
 2 /// 將公鑰保存到文件中  3 /// </summary>
 4 /// <param name="rsa"></param>
 5 /// <param name="fileName"></param>
 6 static void SaveKey2File(RSACryptoServiceProvider rsa, string fileName)  7 {  8     FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);  9 
10     string key = rsa.ToXmlString(false);    //公鑰
11     fs.Write(Encoding.UTF8.GetBytes(key), 0, key.Length); 12             
13  fs.Close(); 14  fs.Dispose(); 15 } 16 
17 
18 /// <summary>
19 /// 從文件中加載rsa得到秘鑰 20 /// </summary>
21 /// <param name="rsa"></param>
22 /// <param name="fileName"></param>
23 static void LoadKeyFromFile(RSACryptoServiceProvider rsa, string fileName) 24 { 25     FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); 26             
27     byte[] data = new byte[fs.Length]; 28     fs.Read(data, 0, (int)fs.Length); 29             
30  fs.Close(); 31  fs.Dispose(); 32             
33  rsa.FromXmlString(Encoding.UTF8.GetString(data)); 34 }
View Code

 

2.將秘鑰保存到秘鑰容器中

什么是密鑰容器(key container)呢?Window系統提供兩種密鑰庫(key store)用來保存密鑰(User Key Store和Machine Key Store),而密鑰容器就是用來保存密鑰的一個單位,每個密鑰容器都包含了一組密鑰對(公鑰和私鑰)和一些其它的信息,例如是否允許導出密鑰,密鑰的種類(Exchange或Signatrue)等等,我們可以通過密鑰容器的名稱來訪問它們。

使用CspParameters對象創建或使用密鑰容器:

 1 //實例化CspParameters對象
 2 CspParameters cspPara = new CspParameters();  3 
 4 //指定CspParameters對象實例的名稱
 5 cspPara.KeyContainerName = "key_container_test";  6 
 7 //設置密鑰類型為Exchange
 8 cspPara.KeyNumber = 1;  9 
10 //設置密鑰容器保存到計算機密鑰庫(默認為用戶密鑰庫)
11 cspPara.Flags = CspProviderFlags.UseMachineKeyStore; 12 
13 //實例化RSA對象的時候,將CspParameters對象作為構造函數的參數傳遞給RSA對象, 14 //如果名稱為key_container_test的密鑰容器不存在,RSA對象會創建這個密鑰容器; 15 //如果名稱為key_container_test的密鑰容器已經存在,RSA對象會使用這個密鑰容器中的密鑰進行實例化
16 RSACryptoServiceProvider rsaPro = new RSACryptoServiceProvider(cspPara);

刪除密鑰容器:當我們不再需要某個密鑰容器的時候,可以使用下面的方法進行刪除。

 1 CspParameters cspPara = new CspParameters();  2 
 3 cspPara.KeyContainerName = "key_container_test";  4 cspPara.Flags = CspProviderFlags.UseMachineKeyStore;  5 RSACryptoServiceProvider rsaPro = new RSACryptoServiceProvider(cspPara);  6 
 7 //不在密鑰庫中保存此密鑰容器
 8 rsaPro.PersistKeyInCsp = false;  9 
10 //釋放rsaPro占用的所有資源,包括密鑰容器。
11 rsaPro.Clear();

除非知道密鑰容器的名稱,否則無法從密鑰庫中提取到這個密鑰容器,所以在本機使用的密鑰(尤其是私鑰)保存在密鑰容器中是比較安全的做法。

注:實際當我們實例化一個RSACryptoServiceProvider 對象的時候,如果不指定具體的CspParameters 對象,RSACryptoServiceProvider 對象會生成一個臨時的密鑰容器,並且在RSACryptoServiceProvider 對象銷毀的時候自動刪除這個臨時的密鑰容器。

 

3.使用數字證書

如果你的密鑰需要在不同的機器上使用,那么將密鑰保存在數字證書中是一個不錯的選擇。實際上,說將密鑰保存在數字證書中並不准確,應該是先生成一個數字證書,然后在使用數字證書中的密鑰。

如何生成一個數字證書呢?正式的數字證書需要到CA去申請,當然還要奉上一筆銀子。還好我們可以使用.Net SDK提供的MakeCert.exe來生成臨時的數字證書。具體如何生成請訪問證書創建工具

.Net中用來訪問證書的對象是X509Certificate2,我們可以用它來加載一個數字證書並獲得數字證書中的密鑰。

如果證書是以文件的形式保存在本地的話,可以用下面的方法加載:

 1 static byte[] EncryptDataByCert(byte[] data)  2 {  3     //實例化一個X509Certificate2對象,並加載證書testCertificate.cer
 4     X509Certificate2 cert = new X509Certificate2(@"c:\testCertificate.cer");  5 
 6     //將證書的公鑰強制轉換成一個RSACryptoServiceProvider對象,然后可以使用這個對象執行加密操作
 7     RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;  8     byte[] enData = rsa.Encrypt(data, false);  9 
10     return enData; 11 }

一般情況下,對於數字證書來說,保存公鑰的證書使用.cer做擴展名,而保存了私鑰的證書會使用.pfx做擴展名,當我們加載一個私鑰的數字證書時,需要提供私鑰的保護密碼,代碼如下:

 1 static string DecryptByCert(byte[] endata)  2 {  3     //實例化一個X509Certificate2對象,並加載證書testCertificate.pfx。  4     //由於證書testCertificate.pfx包含私鑰,所以需要提供私鑰的保護密碼(第二個參數)
 5     X509Certificate2 cert = new X509Certificate2(@"c:\testCertificate.pfx", "123456");  6 
 7     //將證書testCertificate.pfx的私鑰強制轉換為一個RSACryptoServiceProvider對象,用於解密操作
 8     RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;  9     byte[] data = rsa.Decrypt(endata, false); 10 
11     return data; 12 }

如果證書保存在計算機的證書存儲區(Certificate Store)中,我們就需要使用另一個對象X509Store來訪問證書存儲區。根據訪問權限,證書存儲區分為當前用戶(Current User)和本地計算機(Local Machine)兩個部分,前者用來保存當前登錄的用戶所能使用的數字證書,而后者用來保存登錄到本機所能使用的數字證書。不管是當前用戶還是本地計算機,都包含多個邏輯存儲區,它們通過不同的名稱來區分,每個邏輯存儲區可以保存多個數字證書。更詳細的介紹,可以參考證書。具體的訪問證書存儲區的代碼如下:

 1 private X509Certificate2 GetCertificate(string CertName)  2 {  3     //聲明X509Store對象,指定存儲區的名稱和存儲區的類型  4     //StoreName中定義了系統默認的一些存儲區的邏輯名稱
 5     X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);  6     //以只讀的方式打開這個存儲區,OpenFlags定義的打開的方式
 7  store.Open(OpenFlags.ReadOnly);  8     //獲取這個存儲區中的數字證書的集合
 9     X509Certificate2Collection certCol = store.Certificates; 10     //查找滿足證書名稱的證書並返回
11     foreach (X509Certificate2 cert in certCol) 12  { 13         if (cert.SubjectName.Name == "CN=" + CertName) 14  { 15  store.Close(); 16             return cert; 17  } 18  } 19  store.Close(); 20     return null; 21 }

我們也可以通過X509Certificate2Collection 對象在當前存儲區中添加刪除證書,詳細的信息可以參考證書存儲區

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM