RSA简介
RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。
RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。即RSA的重大缺陷是无法从理论上把握它的保密性能如何,而且密码学界多数人士倾向于因子分解不是NPC问题。RSA的缺点主要有:
A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。
B)分组长度太大,为保证安全性,n 至少也要 600bits以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。目前,SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。
C)RSA密钥长度随着保密级别提高,增加很快。下表列出了对同一安全级别所对应的密钥长度。
这种算法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)就是密钥对。
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;
1.RSA加密解密:
(1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密
2.RSA签名和验证
(1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)获取待签名的Hash码 (3)获取签名的字符串 (4)验证
3.公钥与私钥的理解:
(1)私钥用来进行解密和签名,是给自己用的。
(2)公钥由本人公开,用于加密和验证签名,是给别人用的。
(3)当该用户A:发送文件时,用私钥签名,用户B:用A给的公钥验证签名,可以保证该信息是由A发送的。当该用户A接受文件时,B用A的公钥加密,A用私钥解密,B的公钥是正确的。
核心代码如下,注意加密解密和签名分开,如不懂可以联系我 www.luofenming.com
using System; using System.Collections; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading; namespace RSA { class RASCrypion { #region RSA 加密解密 #region RSA 的密钥产生 /// <summary> /// RSA产生密钥 /// </summary> /// <param name="xmlKeys">私钥</param> /// <param name="xmlPublicKey">公钥</param> public void RSAKey(out string xmlKeys, out string xmlPublicKey) { try { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); xmlKeys = rsa.ToXmlString(true); xmlPublicKey = rsa.ToXmlString(false); } catch (Exception ex) { throw ex; } } #endregion #region RSA加密函数 //############################################################################## //RSA 方式加密 //KEY必须是XML的形式,返回的是字符串 //该加密方式有长度限制的! //############################################################################## /// <summary> /// RSA的加密函数 /// </summary> /// <param name="xmlPublicKey">公钥</param> /// <param name="encryptString">待加密的字符串</param> /// <returns></returns> public string RSAEncrypt(string xmlPublicKey, string encryptString) { try { byte[] PlainTextBArray; byte[] CypherTextBArray; StringBuilder result = new StringBuilder(); string temp; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(xmlPublicKey); PlainTextBArray = (new UnicodeEncoding()).GetBytes(encryptString); double count = Math.Ceiling(PlainTextBArray.Length / 117.0); for (int i = 0; i < count; i++) { //最长117个字节加密后生成一个固定长度128个字节(不管多少位字节都是生成128个字节) CypherTextBArray = rsa.Encrypt(PlainTextBArray.Skip(i * 117).Take(117).ToArray(), false); temp = Convert.ToBase64String(CypherTextBArray); result.Append(temp); } return result.ToString(); ; } catch (Exception ex) { throw ex; } } /// <summary> /// RSA的加密函数 /// </summary> /// <param name="xmlPublicKey">公钥</param> /// <param name="EncryptString">待加密的字节数组</param> /// <returns></returns> public string RSAEncrypt(string xmlPublicKey, byte[] EncryptString) { try { byte[] CypherTextBArray; StringBuilder result = new StringBuilder(); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(xmlPublicKey); double count = Math.Ceiling(EncryptString.Length / 117.0); for (int i = 0; i < count; i++) { CypherTextBArray = rsa.Encrypt(EncryptString, false); result.Append(Convert.ToBase64String(CypherTextBArray)); } return result.ToString(); } catch (Exception ex) { throw ex; } } /// <summary> /// 加密文件 /// </summary> /// <param name="filename"></param> /// <param name="key"></param> /// <returns></returns> public bool RSAEncryptFile(string filename, string key) { FileStream f; try { f = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); } catch { return false; } Random r = new Random(); Thread.Sleep(10 * r.Next(3, 8)); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024); rsa.FromXmlString(key); //导入密钥 byte[] data = new byte[117]; ArrayList con = new ArrayList(); while (f.Read(data, 0, 117) != 0) { byte[] result = rsa.Encrypt(data, false); //Thread.Sleep(10 * r.Next(2, 7)); con.Add(result); } //加密 f.Seek(0, SeekOrigin.Begin); foreach (byte[] d in con) { f.Write(d, 0, d.Length); } f.Close(); return true; } #endregion #region RSA的解密函数 /// <summary> /// RSA的解密函数 /// </summary> /// <param name="xmlPrivateKey">私钥</param> /// <param name="decryptString">待解密的字符串</param> /// <returns></returns> public string RSADecrypt(string xmlPrivateKey, string decryptString) { try { byte[] PlainTextBArray; byte[] DypherTextBArray; StringBuilder result = new StringBuilder(); string temp = string.Empty; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(xmlPrivateKey); int count = decryptString.Length / 172; for (int i = 0; i < count; i++) { //加密之后为128字节转 Convert.ToBase64String 的长度为固定长度172 PlainTextBArray = Convert.FromBase64String(decryptString.Substring(i * 172, 172)); DypherTextBArray = rsa.Decrypt(PlainTextBArray, false); temp = (new UnicodeEncoding()).GetString(DypherTextBArray); result.Append(temp); } return result.ToString(); } catch (Exception ex) { throw ex; } } /// <summary> /// RSA的解密函数 /// </summary> /// <param name="xmlPrivateKey">私钥</param> /// <param name="DecryptString">待解密的字节数组</param> /// <returns></returns> public string RSADecrypt(string xmlPrivateKey, byte[] DecryptString) { try { byte[] DypherTextBArray; StringBuilder result = new StringBuilder(); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(xmlPrivateKey); int count = DecryptString.Length / 128;//因为加密的Byte固定长度是128 for (int i = 0; i < count; i++) { DypherTextBArray = rsa.Decrypt(DecryptString.Skip(i * 128).Take(128).ToArray(), false); result.Append((new UnicodeEncoding()).GetString(DypherTextBArray)); } return result.ToString(); } catch (Exception ex) { throw ex; } } /// <summary> /// 解密文件 /// </summary> /// <param name="filename"></param> /// <param name="key"></param> /// <returns></returns> public bool RSADecryptFile(string filename, string key) { FileStream f; try { f = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); } catch (Exception ex) { return false; } RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024); try { rsa.FromXmlString(key); } catch { return false; } byte[] data = new byte[128]; ArrayList con = new ArrayList(); while (f.Read(data, 0, 128) != 0) { byte[] result; try { result = rsa.Decrypt(data, false); } catch (Exception ex) { return false; } con.Add(result); } //解密 f.SetLength(con.Count * 16); f.Seek(0, SeekOrigin.Begin); foreach (byte[] d in con) { f.Write(d, 0, d.Length); } f.Close(); return true; } #endregion #endregion #region RSA数字签名 #region 获取Hash描述表 /// <summary> /// 获取Hash描述表 /// </summary> /// <param name="strSource">待签名的字符串</param> /// <param name="HashData">Hash描述</param> /// <returns></returns> public bool GetHash(string strSource, ref byte[] HashData) { try { byte[] Buffer; HashAlgorithm MD5 = HashAlgorithm.Create("MD5"); Buffer = System.Text.Encoding.GetEncoding("GB2312").GetBytes(strSource); HashData = MD5.ComputeHash(Buffer); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// 获取Hash描述表 /// </summary> /// <param name="strSource">待签名的字符串</param> /// <param name="strHashData">Hash描述</param> /// <returns></returns> public bool GetHash(string strSource, ref string strHashData) { try { //从字符串中取得Hash描述 byte[] Buffer; byte[] HashData; HashAlgorithm MD5 = HashAlgorithm.Create("MD5"); Buffer = System.Text.Encoding.GetEncoding("GB2312").GetBytes(strSource); HashData = MD5.ComputeHash(Buffer); strHashData = Convert.ToBase64String(HashData); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// 获取Hash描述表 /// </summary> /// <param name="objFile">待签名的文件</param> /// <param name="HashData">Hash描述</param> /// <returns></returns> public bool GetHash(System.IO.FileStream objFile, ref byte[] HashData) { try { //从文件中取得Hash描述 HashAlgorithm MD5 = HashAlgorithm.Create("MD5"); HashData = MD5.ComputeHash(objFile); objFile.Close(); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// 获取Hash描述表 /// </summary> /// <param name="objFile">待签名的文件</param> /// <param name="strHashData">Hash描述</param> /// <returns></returns> public bool GetHash(System.IO.FileStream objFile, ref string strHashData) { try { //从文件中取得Hash描述 byte[] HashData; HashAlgorithm MD5 = HashAlgorithm.Create("MD5"); HashData = MD5.ComputeHash(objFile); objFile.Close(); strHashData = Convert.ToBase64String(HashData); return true; } catch (Exception ex) { throw ex; } } #endregion #region RSA签名 /// <summary> /// RSA签名 /// </summary> /// <param name="strKeyPrivate">私钥</param> /// <param name="HashbyteSignature">待签名Hash描述</param> /// <param name="EncryptedSignatureData">签名后的结果</param> /// <returns></returns> public bool SignatureFormatter(string strKeyPrivate, byte[] HashbyteSignature, ref byte[] EncryptedSignatureData) { try { RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(strKeyPrivate); RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA); //设置签名的算法为MD5 RSAFormatter.SetHashAlgorithm("MD5"); //执行签名 EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// RSA签名 /// </summary> /// <param name="strKeyPrivate">私钥</param> /// <param name="HashbyteSignature">待签名Hash描述</param> /// <param name="m_strEncryptedSignatureData">签名后的结果</param> /// <returns></returns> public bool SignatureFormatter(string strKeyPrivate, byte[] HashbyteSignature, ref string strEncryptedSignatureData) { try { byte[] EncryptedSignatureData; RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(strKeyPrivate); RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA); //设置签名的算法为MD5 RSAFormatter.SetHashAlgorithm("MD5"); //执行签名 EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature); strEncryptedSignatureData = Convert.ToBase64String(EncryptedSignatureData); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// RSA签名 /// </summary> /// <param name="strKeyPrivate">私钥</param> /// <param name="strHashbyteSignature">待签名Hash描述</param> /// <param name="EncryptedSignatureData">签名后的结果</param> /// <returns></returns> public bool SignatureFormatter(string strKeyPrivate, string strHashbyteSignature, ref byte[] EncryptedSignatureData) { try { byte[] HashbyteSignature; HashbyteSignature = Convert.FromBase64String(strHashbyteSignature); RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(strKeyPrivate); RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA); //设置签名的算法为MD5 RSAFormatter.SetHashAlgorithm("MD5"); //执行签名 EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature); return true; } catch (Exception ex) { throw ex; } } /// <summary> /// RSA签名 /// </summary> /// <param name="strKeyPrivate">私钥</param> /// <param name="strHashbyteSignature">待签名Hash描述</param> /// <param name="strEncryptedSignatureData">签名后的结果</param> /// <returns></returns> public bool SignatureFormatter(string strKeyPrivate, string strHashbyteSignature, ref string strEncryptedSignatureData) { try { byte[] HashbyteSignature; byte[] EncryptedSignatureData; HashbyteSignature = Convert.FromBase64String(strHashbyteSignature); RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(strKeyPrivate); RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA); //设置签名的算法为MD5 RSAFormatter.SetHashAlgorithm("MD5"); //执行签名 EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature); strEncryptedSignatureData = Convert.ToBase64String(EncryptedSignatureData); return true; } catch (Exception ex) { throw ex; } } #endregion #region RSA 签名验证 /// <summary> /// RSA签名验证 /// </summary> /// <param name="strKeyPublic">公钥</param> /// <param name="HashbyteDeformatter">Hash描述</param> /// <param name="DeformatterData">签名后的结果</param> /// <returns></returns> public bool SignatureDeformatter(string strKeyPublic, byte[] HashbyteDeformatter, byte[] DeformatterData) { try { RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(strKeyPublic); RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(RSA); //指定解密的时候HASH算法为MD5 RSADeformatter.SetHashAlgorithm("MD5"); if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData)) { return true; } else { return false; } } catch (Exception ex) { throw ex; } } /// <summary> /// RSA签名验证 /// </summary> /// <param name="strKeyPublic">公钥</param> /// <param name="strHashbyteDeformatter">Hash描述</param> /// <param name="DeformatterData">签名后的结果</param> /// <returns></returns> public bool SignatureDeformatter(string strKeyPublic, string strHashbyteDeformatter, byte[] DeformatterData) { try { byte[] HashbyteDeformatter; HashbyteDeformatter = Convert.FromBase64String(strHashbyteDeformatter); RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(strKeyPublic); RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(RSA); //指定解密的时候HASH算法为MD5 RSADeformatter.SetHashAlgorithm("MD5"); if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData)) { return true; } else { return false; } } catch (Exception ex) { throw ex; } } /// <summary> /// RSA签名验证 /// </summary> /// <param name="strKeyPublic">公钥</param> /// <param name="HashbyteDeformatter">Hash描述</param> /// <param name="strDeformatterData">签名后的结果</param> /// <returns></returns> public bool SignatureDeformatter(string strKeyPublic, byte[] HashbyteDeformatter, string strDeformatterData) { try { byte[] DeformatterData; RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(strKeyPublic); RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(RSA); //指定解密的时候HASH算法为MD5 RSADeformatter.SetHashAlgorithm("MD5"); DeformatterData = Convert.FromBase64String(strDeformatterData); if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData)) { return true; } else { return false; } } catch (Exception ex) { throw ex; } } /// <summary> /// RSA签名验证 /// </summary> /// <param name="strKeyPublic">公钥</param> /// <param name="strHashbyteDeformatter">Hash描述</param> /// <param name="strDeformatterData">签名后的结果</param> /// <returns></returns> public bool SignatureDeformatter(string strKeyPublic, string strHashbyteDeformatter, string strDeformatterData) { try { byte[] DeformatterData; byte[] HashbyteDeformatter; HashbyteDeformatter = Convert.FromBase64String(strHashbyteDeformatter); RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSA.FromXmlString(strKeyPublic); RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(RSA); //指定解密的时候HASH算法为MD5 RSADeformatter.SetHashAlgorithm("MD5"); DeformatterData = Convert.FromBase64String(strDeformatterData); if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData)) { return true; } else { return false; } } catch (Exception ex) { throw ex; } } #endregion #endregion } }