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 }
三、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 对象在当前存储区中添加删除证书,详细的信息可以参考证书存储区。