C# RSA非对称加密实现

RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。
SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。C)RSA密钥长度随着保密级别提高,增加很快。下表列出了对同一安全级别所对应的密钥长度。
保密级别
对称密钥长度(bit)
RSA密钥长度(bit)
ECC密钥长度(bit)
保密年限
80
80
1024
160
2010
112
112
2048
224
2030
128
128
3072
256
2040
192
192
7680
384
2080
256
256
15360
512
2120
这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest,AdiShamir 和Leonard Adleman。早在1973年,英国国家通信总局的数学家Clifford Cocks就发现了类似的算法。但是他的发现被列为绝密,直到1998年才公诸于世。
RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
RSA的算法涉及三个参数,n、e1、e2。
其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。
e1和e2是一对相关的值,e1可以任意取,但要求e1与(p-1)*(q-1)互质;再选择e2,要求(e2*e1)mod((p-1)*(q-1))=1。
(n,e1),(n,e2)就是密钥对。其中(n,e1)为公钥(n,e2)为私钥。[1] 
RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e2 mod n;B=A^e1 mod n;(公钥加密体制中,一般用公钥加密,私钥解密)
e1和e2可以互换使用,即:
A=B^e1 mod n;B=A^e2 mod n;
 
以下是c#实现:
 1        public ActionResult TestRSA()
 2         {
 3             var str = GenerateKeys();
 4             string source = EncryptString("xuxzx", str[1]);
 5    
 6             return Content(DecryptString(source, str[0]));
 7         }
 8 
 9 
10         /// <summary>
11         /// generate private key and public key arr[0] for private key arr[1] for public key
12         /// </summary>
13         /// <returns></returns>
14         public static string[] GenerateKeys()
15       {
16           string[] sKeys = new String[2];
17           RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
18           sKeys[0] = rsa.ToXmlString(true); //private
19             sKeys[1] = rsa.ToXmlString(false);//public
20           return sKeys;
21       }
22 
23         /// <summary>
24         /// RSA Encrypt
25         /// </summary>
26         /// <param name="sSource" >Source string</param>
27         /// <param name="sPublicKey" >public key</param>
28         /// <returns></returns>
29         public string EncryptString(string sSource, string sPublicKey)
30         {
31             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
32             string plaintext = sSource;
33             rsa.FromXmlString(sPublicKey);
34             byte[] cipherbytes;
35             byte[] byteEn = rsa.Encrypt(Encoding.UTF8.GetBytes("a"), false);
36             cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(plaintext), false);
37             StringBuilder sbString = new StringBuilder();
38             for (int i = 0; i < cipherbytes.Length; i++)
39             {
40                 sbString.Append(cipherbytes[i] + ",");
41             }
42             return sbString.ToString();
43         }
44 
45         /// <summary>
46         /// RSA Decrypt
47         /// </summary>
48         /// <param name="sSource">Source string</param>
49         /// <param name="sPrivateKey">Private Key</param>
50         /// <returns></returns>
51         public string DecryptString(String sSource, string sPrivateKey)
52         {
53             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
54             rsa.FromXmlString(sPrivateKey);
55             byte[] byteEn = rsa.Encrypt(Encoding.UTF8.GetBytes("a"), false);
56             string[] sBytes = sSource.Split(',');
57             for (int j = 0; j < sBytes.Length; j++)
58             {
59                 if (sBytes[j] != "")
60                 {
61                     byteEn[j] = Byte.Parse(sBytes[j]);
62                 }
63             }
64             byte[] plaintbytes = rsa.Decrypt(byteEn, false);
65             return Encoding.UTF8.GetString(plaintbytes);
66         }

 

posted @ 2015-01-26 13:38  xuxzx  阅读(1455)  评论(0编辑  收藏  举报