一、知識點
對稱加密的代表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 }
三、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 }
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 對象在當前存儲區中添加刪除證書,詳細的信息可以參考證書存儲區。