轉自:http://blog.csdn.net/u010678947/article/details/48652875
一、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;
二、MD5加密介紹
參考:http://blog.csdn.net/wonsoft/article/details/5913572
MD5的全稱是message-digest algorithm 5(信息-摘要算法,在90年代初由mit laboratory for computer science和rsa data security inc的ronald l. rivest開發出來, 經md2、md3和md4發展而來。
MD5具有很好的安全性(因為它具有不可逆的特征,加過密的密文經過解密后和加密前的東東相同的可能性極小)
- public string GetStrMd5(string ConvertString)
- {
- string strBodyBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(ConvertString));
- string t2=System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strBodyBase64, "MD5").ToUpper();
- return t2;
- }
三、C#對PKCS#8編碼的RSA私鑰進行簽名
- /// <summary>
- /// 對MD5加密后的長度為32的密文進行簽名
- /// </summary>
- /// <param name="strPrivateKey">私鑰</param>
- /// <param name="strContent">MD5加密后的密文</param>
- /// <returns></returns>
- public string SignatureFormatter(string strPrivateKey, string strContent)
- {
- byte[] btContent = Encoding.UTF8.GetBytes(strContent);
- byte[] hv = MD5.Create().ComputeHash(btContent);
- RSACryptoServiceProvider rsp = new RSACryptoServiceProvider();
- rsp.FromXmlString(strPrivateKey);
- RSAPKCS1SignatureFormatter rf = new RSAPKCS1SignatureFormatter(rsp);
- rf.SetHashAlgorithm("MD5");
- byte[] signature = rf.CreateSignature(hv);
- return Convert.ToBase64String(signature);
- }
四、C#實現RSA加密與解密、簽名與認證常用方法
1.RSA加密解密:
(1)獲取密鑰,這里是產生密鑰,實際應用中可以從各種存儲介質上讀取密鑰 (2)加密 (3)解密
2.RSA簽名和驗證
(1)獲取密鑰,這里是產生密鑰,實際應用中可以從各種存儲介質上讀取密鑰 (2)獲取待簽名的Hash碼 (3)獲取簽名的字符串 (4)驗證
3.公鑰與私鑰的理解:
(1)私鑰用來進行解密和簽名,是給自己用的。
(2)公鑰由本人公開,用於加密和驗證簽名,是給別人用的。
(3)當該用戶發送文件時,用私鑰簽名,別人用他給的公鑰驗證簽名,可以保證該信息是由他發送的。當該用戶接受文件時,別人用他的公鑰加密,他用私鑰解密,可以保證該信息只能由他接收到。
- using System.Security.Cryptography;
- class RSACryption
- {
- #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
- {
- System.Security.Cryptography.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;
- string Result;
- System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.FromXmlString(xmlPublicKey);
- PlainTextBArray = (new UnicodeEncoding()).GetBytes(encryptString);
- CypherTextBArray = rsa.Encrypt(PlainTextBArray, false);
- Result = Convert.ToBase64String(CypherTextBArray);
- return Result;
- }
- 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;
- string Result;
- System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.FromXmlString(xmlPublicKey);
- CypherTextBArray = rsa.Encrypt(EncryptString, false);
- Result = Convert.ToBase64String(CypherTextBArray);
- return Result;
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #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;
- string Result;
- System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.FromXmlString(xmlPrivateKey);
- PlainTextBArray = Convert.FromBase64String(decryptString);
- DypherTextBArray = rsa.Decrypt(PlainTextBArray, false);
- Result = (new UnicodeEncoding()).GetString(DypherTextBArray);
- return Result;
- }
- 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;
- string Result;
- System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.FromXmlString(xmlPrivateKey);
- DypherTextBArray = rsa.Decrypt(DecryptString, false);
- Result = (new UnicodeEncoding()).GetString(DypherTextBArray);
- return Result;
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #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;
- System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.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;
- System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.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描述
- System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.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;
- System.Security.Cryptography.HashAlgorithm MD5 = System.Security.Cryptography.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
- {
- System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
- RSA.FromXmlString(strKeyPrivate);
- System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.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;
- System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
- RSA.FromXmlString(strKeyPrivate);
- System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.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);
- System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
- RSA.FromXmlString(strKeyPrivate);
- System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.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);
- System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
- RSA.FromXmlString(strKeyPrivate);
- System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.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
- {
- System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
- RSA.FromXmlString(strKeyPublic);
- System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new
- System.Security.Cryptography.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);
- System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
- RSA.FromXmlString(strKeyPublic);
- System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new
- System.Security.Cryptography.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;
- System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
- RSA.FromXmlString(strKeyPublic);
- System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new
- System.Security.Cryptography.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);
- System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
- RSA.FromXmlString(strKeyPublic);
- System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new
- System.Security.Cryptography.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
- }