RSA公鑰加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美國麻省理工學院)開發的。RSA取名來自開發他們三者的名字。RSA是目前最有影響力的公鑰加密算法,它可以抵抗到目前爲止已知的全部密碼攻擊,已被ISO推薦爲公鑰數據加密標準。RSA算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,所以能夠將乘積公開做爲加密密鑰。RSA算法是第一個能同時用於加密和數字簽名的算法,也易於理解和操做。算法
RSA是被研究得最普遍的公鑰算法,從提出到如今已近二十年,經歷了各類攻擊的考驗,逐漸爲人們接受,廣泛認爲是目前最優秀的公鑰方案之一。RSA的安全性依賴於大數的因子分解,但並無從理論上證實破譯RSA的難度與大數分解難度等價。即RSA的重大缺陷是沒法從理論上把握它的保密性能如何,並且密碼學界多數人士傾向於因子分解不是NPC問題。安全
RSA的缺點主要有:ide
A)產生密鑰很麻煩,受到素數產生技術的限制,於是難以作到一次一密。性能
B)分組長度太大,爲保證安全性,n 至少也要 600bits以上,使運算代價很高,尤爲是速度較慢,較對稱密碼算法慢幾個數量級;且隨着大數分解技術的發展,這個ui
長度還在增長,不利於數據格式的標準化。目前,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年才公諸於世。spa
RSA算法是一種非對稱密碼算法,所謂非對稱,就是指該算法須要一對密鑰,使用其中一個加密,則須要用另外一個才能解密。blog
RSA的算法涉及三個參數,n、e一、e2。ip
其中,n是兩個大質數p、q的積,n的二進制表示時所佔用的位數,就是所謂的密鑰長度。 ci
e1和e2是一對相關的值,e1能夠任意取,但要求e1與(p-1)*(q-1)互質;再選擇e2,要求(e2*e1)mod((p-1)*(q-1))=1。
(n及e1),(n及e2)就是密鑰對。
RSA加解密的算法徹底相同,設A爲明文,B爲密文,則:A=B^e1 mod n;B=A^e2 mod n;
e1和e2能夠互換使用,即:
A=B^e2 mod n;B=A^e1 mod n;
C#代碼實現
需引用using System.Security.Cryptography;
/// <summary> /// RSA加密 /// </summary> /// <param name="publickey"></param> /// <param name="content"></param> /// <returns></returns> public static string RSAEncrypt(string publickey, string content) { publickey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); byte[] cipherbytes; rsa.FromXmlString(publickey); cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
return Convert.ToBase64String(cipherbytes); }
/// <summary> /// RSA解密 /// </summary> /// <param name="privatekey"></param> /// <param name="content"></param> /// <returns></returns> public static string RSADecrypt(string privatekey, string content) { privatekey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent><P>/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==</P><Q>6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==</Q><DP>ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==</DP><DQ>MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==</DQ><InverseQ>EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==</InverseQ><D>vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=</D></RSAKeyValue>"; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); byte[] cipherbytes; rsa.FromXmlString(privatekey); cipherbytes = rsa.Decrypt(Convert.FromBase64String(content), false);
return Encoding.UTF8.GetString(cipherbytes); }