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

 

 

posted @ 2021-04-25 10:35  殇琉璃  阅读(970)  评论(0编辑  收藏  举报