RSA算法是第一個能同時用於加密和數字簽名的算法,也易於理解和操做。 RSA是被研究得最普遍的公鑰算法,從提出到如今已近二十年,經歷了各類攻擊的考驗,逐漸爲人們接受,廣泛認爲是目前最優秀的公鑰方案之一。RSA的安全性依賴於大數的因子分解,但並無從理論上證實破譯RSA的難度與大數分解難度等價。html
.NET提供經常使用的加密算法類,支持RSA的類是RSACryptoServiceProvider(命名空間:System.Security.Cryptography),但只支持公鑰加密,私鑰解密。RSACryptoServiceProvider類包括:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D等8個屬性,其中Modulus和Exponent就是公鑰,Modulus和D就是私鑰,RSACryptoServiceProvider類提供導出公鑰的方法,也提供導出私鑰的方法,但導出的私鑰包含上面8個屬性
,顯然要用RSACryptoServiceProvider實現私鑰加密公鑰是不可行的。前端
從RSA的原理來看,公鑰加密私鑰解密和私鑰加密公鑰解密應該是等價的,在某些狀況下,好比共享軟件加密,咱們須要用私鑰加密註冊碼或註冊文件,發給用戶,用戶用公鑰解密註冊碼或註冊文件進行合法性驗證。web
不對稱密鑰
.NET Framework 爲不對稱加密提供了 RSACryptoServiceProvider 和 DSACryptoServiceProvider 類。這些類在您使用默認構造函數建立新實例時建立一個公鑰/私鑰對。既能夠存儲不對稱密鑰以用在多個會話中,也能夠只爲一個會話生成不對稱密鑰。公鑰能夠被普遍地使用,私鑰應被嚴密地保護起來。算法
每當建立不對稱算法類的新實例時,都生成一個公鑰/私鑰對。建立該類的新實例後,能夠用如下兩種方法之一提取密鑰信息:數組
兩個方法都接受布爾值,該值指示是隻返回公鑰信息仍是同時返回公鑰和私鑰信息。經過使用 ImportParameters 方法,能夠將 RSACryptoServiceProvider 類初始化爲 RSAParameters 結構的值。ide
下面的代碼示例建立 RSACryptoServiceProvider 類的一個新實例,建立一個公鑰/私鑰對,並將公鑰信息保存在RSAParameters 結構中函數
- RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
- RSAParameters RSAKeyInfo = RSA.ExportParameters(false);
1、公鑰加密私鑰解密
-
-
- public class RSAEncryptHelper
- {
-
-
-
-
-
-
-
- public string EncodeBase64(string code_type, string code)
- {
- string encode = "";
- byte[] bytes = Encoding.GetEncoding(code_type).GetBytes(code);
- try
- {
- encode = Convert.ToBase64String(bytes);
- }
- catch
- {
- encode = code;
- }
- return encode;
- }
-
-
-
-
-
-
-
- public string DecodeBase64(string code_type, string code)
- {
-
- string decode = "";
- byte[] bytes = Convert.FromBase64String(code);
- try
- {
- decode = Encoding.GetEncoding(code_type).GetString(bytes);
- }
- catch
- {
- decode = code;
- }
- return decode;
- }
-
-
-
-
- public static string GetLocalMac()
- {
- string mac = null;
- ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");
- ManagementObjectCollection queryCollection = query.Get();
- foreach (ManagementObject mo in queryCollection)
- {
- if (mo["IPEnabled"].ToString() == "True")
- mac = mo["MacAddress"].ToString();
- }
- return (mac);
- }
-
-
-
-
-
- public static string GetCpuID()
- {
- try
- {
-
- string cpuInfo = "";
- ManagementClass mc = new ManagementClass("Win32_Processor");
- ManagementObjectCollection moc = mc.GetInstances();
- foreach (ManagementObject mo in moc)
- {
- cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
- }
- moc = null;
- mc = null;
- return cpuInfo;
- }
- catch
- {
- return "unknow";
- }
- finally
- {
- }
-
- }
-
-
-
-
-
-
-
-
-
-
- public void RSAKey(string PrivateKeyPath, string PublicKeyPath)
- {
-
- try
- {
-
- RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
-
- this.CreatePrivateKeyXML(PrivateKeyPath, provider.ToXmlString(true));
-
- this.CreatePublicKeyXML(PublicKeyPath, provider.ToXmlString(false));
-
- }
-
- catch (Exception exception)
- {
-
- throw exception;
-
- }
-
- }
-
-
-
-
-
-
-
-
-
-
-
- public string GetHash(string m_strSource)
- {
-
- HashAlgorithm algorithm = HashAlgorithm.Create("MD5");
-
- byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(m_strSource);
-
- byte[] inArray = algorithm.ComputeHash(bytes);
-
- return Convert.ToBase64String(inArray);
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
- {
-
- string str2;
-
- try
- {
-
- RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
-
- provider.FromXmlString(xmlPublicKey);
-
- byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);
-
- str2 = Convert.ToBase64String(provider.Encrypt(bytes, false));
-
- }
-
- catch (Exception exception)
- {
-
- throw exception;
-
- }
-
- return str2;
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
- {
-
- string str2;
-
- try
- {
-
- RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
-
- provider.FromXmlString(xmlPrivateKey);
-
- byte[] rgb = Convert.FromBase64String(m_strDecryptString);
-
- byte[] buffer2 = provider.Decrypt(rgb, false);
-
- str2 = new UnicodeEncoding().GetString(buffer2);
-
- }
- catch (Exception exception)
- {
-
- throw exception;
-
- }
-
- return str2;
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- public string SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature)
- {
-
- byte[] rgbHash = Convert.FromBase64String(m_strHashbyteSignature);
-
- RSACryptoServiceProvider key = new RSACryptoServiceProvider();
-
- key.FromXmlString(p_strKeyPrivate);
-
- RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
-
- formatter.SetHashAlgorithm("MD5");
-
- byte[] inArray = formatter.CreateSignature(rgbHash);
-
- return Convert.ToBase64String(inArray);
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData)
- {
-
- try
- {
-
- byte[] rgbHash = Convert.FromBase64String(p_strHashbyteDeformatter);
-
- RSACryptoServiceProvider key = new RSACryptoServiceProvider();
-
- key.FromXmlString(p_strKeyPublic);
-
- RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
-
- deformatter.SetHashAlgorithm("MD5");
-
- byte[] rgbSignature = Convert.FromBase64String(p_strDeformatterData);
-
- if (deformatter.VerifySignature(rgbHash, rgbSignature))
- {
-
- return true;
-
- }
-
- return false;
-
- }
-
- catch
- {
-
- return false;
-
- }
-
- }
-
-
-
-
-
-
-
-
-
- public string GetHardID()
- {
-
- string HDInfo = "";
-
- ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");
-
- ManagementObjectCollection moc1 = cimobject1.GetInstances();
-
- foreach (ManagementObject mo in moc1)
- {
-
- HDInfo = (string)mo.Properties["Model"].Value;
-
- }
-
- return HDInfo;
-
- }
-
-
-
-
-
-
-
-
-
-
-
- private string ReadReg(string key)
- {
-
- string temp = "";
-
- try
- {
-
- RegistryKey myKey = Registry.LocalMachine;
-
- RegistryKey subKey = myKey.OpenSubKey(@"SOFTWARE/JX/Register");
-
-
-
- temp = subKey.GetValue(key).ToString();
-
- subKey.Close();
-
- myKey.Close();
-
- return temp;
-
- }
-
- catch (Exception)
- {
-
- throw;
-
- }
-
-
-
- }
-
-
-
-
-
-
-
-
-
-
-
- private void WriteReg(string key, string value)
- {
-
- try
- {
-
- RegistryKey rootKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");
-
- rootKey.SetValue(key, value);
-
- rootKey.Close();
-
- }
-
- catch (Exception)
- {
-
- throw;
-
- }
-
- }
-
-
-
-
-
-
-
-
-
-
-
- public void CreatePublicKeyXML(string path, string publickey)
- {
-
- try
- {
-
- FileStream publickeyxml = new FileStream(path, FileMode.Create);
-
- StreamWriter sw = new StreamWriter(publickeyxml);
-
- sw.WriteLine(publickey);
-
- sw.Close();
-
- publickeyxml.Close();
-
- }
-
- catch
- {
-
- throw;
-
- }
-
- }
-
-
-
-
-
-
-
-
-
-
-
- public void CreatePrivateKeyXML(string path, string privatekey)
- {
-
- try
- {
-
- FileStream privatekeyxml = new FileStream(path, FileMode.Create);
-
- StreamWriter sw = new StreamWriter(privatekeyxml);
-
- sw.WriteLine(privatekey);
-
- sw.Close();
-
- privatekeyxml.Close();
-
- }
-
- catch
- {
-
- throw;
-
- }
-
- }
-
-
-
-
-
-
-
-
-
-
-
- public string ReadPublicKey(string path)
- {
-
- StreamReader reader = new StreamReader(path);
-
- string publickey = reader.ReadToEnd();
-
- reader.Close();
-
- return publickey;
-
- }
-
-
-
-
-
-
-
-
-
-
-
- public string ReadPrivateKey(string path)
- {
-
- StreamReader reader = new StreamReader(path);
-
- string privatekey = reader.ReadToEnd();
-
- reader.Close();
-
- return privatekey;
-
- }
-
-
-
-
-
-
-
-
-
- public void InitialReg(string path)
- {
-
- Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");
-
- Random ra = new Random();
-
- string publickey = this.ReadPublicKey(path);
-
- if (Registry.LocalMachine.OpenSubKey(@"SOFTWARE/JX/Register").ValueCount <= 0)
- {
-
- this.WriteReg("RegisterRandom", ra.Next(1, 100000).ToString());
-
- this.WriteReg("RegisterPublicKey", publickey);
-
- }
-
- else
- {
-
- this.WriteReg("RegisterPublicKey", publickey);
-
- }
-
- }
- }
2、私鑰加密公鑰解密
-
-
-
-
-
-
-
-
- public static class RSAHelper
- {
-
-
-
- public const int DWKEYSIZE = 1024;
-
-
-
-
-
-
-
-
-
-
- #region 獲得RSA的解謎的密匙對
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #endregion
-
- #region 檢查明文的有效性 DWKEYSIZE/8-11 長度以內爲有效 中英文都算一個字符
-
-
-
-
-
- public static bool CheckSourceValidate(string source)
- {
- return (DWKEYSIZE / 8 - 11) >= source.Length;
- }
- #endregion
-
- #region 組合解析密匙
-
-
-
-
-
-
- public static string ComponentKey(byte[] b1, byte[] b2)
- {
- List<byte> list = new List<byte>();
-
- list.Add((byte)b1.Length);
- list.AddRange(b1);
- list.AddRange(b2);
- byte[] b = list.ToArray<byte>();
- return Convert.ToBase64String(b);
- }
-
-
-
-
-
-
-
- private static void ResolveKey(string key, out byte[] b1, out byte[] b2)
- {
-
- byte[] b = Convert.FromBase64String(key);
-
- b1 = new byte[b[0]];
- b2 = new byte[b.Length - b[0] - 1];
-
- for (int n = 1, i = 0, j = 0; n < b.Length; n++)
- {
- if (n <= b[0])
- {
- b1[i++] = b[n];
- }
- else
- {
- b2[j++] = b[n];
- }
- }
- }
- #endregion
-
- #region 字符串加密解密 公開方法
-
-
-
-
-
-
- public static string EncryptString(string source, string key)
- {
- string encryptString = string.Empty;
- byte[] d;
- byte[] n;
- try
- {
- if (!CheckSourceValidate(source))
- {
- throw new Exception("source string too long");
- }
-
- ResolveKey(key, out d, out n);
- BigInteger biN = new BigInteger(n);
- BigInteger biD = new BigInteger(d);
- encryptString = EncryptString(source, biD, biN);
- }
- catch
- {
- encryptString = source;
- }
- return encryptString;
- }
-
-
-
-
-
-
-
- public static string DecryptString(string encryptString, string key)
- {
- string source = string.Empty;
- byte[] e;
- byte[] n;
- try
- {
-
- ResolveKey(key, out e, out n);
- BigInteger biE = new BigInteger(e);
- BigInteger biN = new BigInteger(n);
- source = DecryptString(encryptString, biE, biN);
- }
- catch
- {
- }
- return source;
- }
- #endregion
-
- #region 字符串加密解密 私有 實現加解密的實現方法
-
-
-
-
-
-
-
- private static string EncryptString(string source, BigInteger d, BigInteger n)
- {
- int len = source.Length;
- int len1 = 0;
- int blockLen = 0;
- if ((len % 128) == 0)
- len1 = len / 128;
- else
- len1 = len / 128 + 1;
- string block = "";
- StringBuilder result = new StringBuilder();
- for (int i = 0; i < len1; i++)
- {
- if (len >= 128)
- blockLen = 128;
- else
- blockLen = len;
- block = source.Substring(i * 128, blockLen);
- byte[] oText = System.Text.Encoding.Default.GetBytes(block);
- BigInteger biText = new BigInteger(oText);
- BigInteger biEnText = biText.modPow(d, n);
- string temp = biEnText.ToHexString();
- result.Append(temp).Append("@");
- len -= blockLen;
- }
- return result.ToString().TrimEnd('@');
- }
-
-
-
-
-
-
-
-
- private static string DecryptString(string encryptString, BigInteger e, BigInteger n)
- {
- StringBuilder result = new StringBuilder();
- string[] strarr1 = encryptString.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
- for (int i = 0; i < strarr1.Length; i++)
- {
- string block = strarr1[i];
- BigInteger biText = new BigInteger(block, 16);
- BigInteger biEnText = biText.modPow(e, n);
- string temp = System.Text.Encoding.Default.GetString(biEnText.getBytes());
- result.Append(temp);
- }
- return result.ToString();
- }
- #endregion
-
-
-
-
-
-
-
-
- public static string EncodeBase64(string code_type, string code)
- {
- string encode = "";
- byte[] bytes = Encoding.GetEncoding(code_type).GetBytes(code);
- try
- {
- encode = Convert.ToBase64String(bytes);
- }
- catch
- {
- encode = code;
- }
- return encode;
- }
-
-
-
-
-
-
-
- public static string DecodeBase64(string code_type, string code)
- {
-
- string decode = "";
- byte[] bytes = Convert.FromBase64String(code);
- try
- {
- decode = Encoding.GetEncoding(code_type).GetString(bytes);
- }
- catch
- {
- decode = code;
- }
- return decode;
- }
-
-
-
-
-
-
-
- public static RSAParameters ReadKey(bool includePrivateparameters,string path)
- {
- using (StreamReader reader = new StreamReader(path))
- {
- string publickey = reader.ReadToEnd();
- RSACryptoServiceProvider rcp = new RSACryptoServiceProvider();
- rcp.FromXmlString(publickey);
- return rcp.ExportParameters(includePrivateparameters);
- }
- }
-
-
-
-
-
- public static string GetLocalMac()
- {
- string mac = null;
- ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");
- ManagementObjectCollection queryCollection = query.Get();
- foreach (ManagementObject mo in queryCollection)
- {
- if (mo["IPEnabled"].ToString() == "True")
- mac = mo["MacAddress"].ToString();
- }
- return (mac);
- }
-
-
-
-
-
- public static string GetCpuID()
- {
- try
- {
-
- string cpuInfo = "";
- ManagementClass mc = new ManagementClass("Win32_Processor");
- ManagementObjectCollection moc = mc.GetInstances();
- foreach (ManagementObject mo in moc)
- {
- cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
- }
- moc = null;
- mc = null;
- return cpuInfo;
- }
- catch
- {
- return "unknow";
- }
- finally
- {
- }
-
- }
-
-
-
-
-
-
-
-
-
- public static string GetHardID()
- {
-
- string HDInfo = "";
-
- ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");
-
- ManagementObjectCollection moc1 = cimobject1.GetInstances();
-
- foreach (ManagementObject mo in moc1)
- {
-
- HDInfo = (string)mo.Properties["Model"].Value;
-
- }
-
- return HDInfo;
-
- }
-
-
-
-
-
-
-
-
-
-
-
- private static string ReadReg(string key)
- {
-
- string temp = "";
-
- try
- {
-
- RegistryKey myKey = Registry.LocalMachine;
-
- RegistryKey subKey = myKey.OpenSubKey(@"SOFTWARE/JX/Register");
-
-
-
- temp = subKey.GetValue(key).ToString();
-
- subKey.Close();
-
- myKey.Close();
-
- return temp;
-
- }
-
- catch (Exception)
- {
-
- throw;
-
- }
- }
-
-
-
-
-
-
-
-
-
-
-
- private static void WriteReg(string key, string value)
- {
- try
- {
-
- RegistryKey rootKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");
-
- rootKey.SetValue(key, value);
-
- rootKey.Close();
-
- }
-
- catch (Exception)
- {
-
- throw;
-
- }
-
- }
-
-
- }
使用場景:如共享軟件加密,咱們須要用私鑰加密註冊碼或註冊文件,發給用戶,用戶用公鑰解密註冊碼或註冊文件進行合法性驗證。
RSA算法實現激活碼註冊方式的原理以下:
1. 生成一對公鑰E和私鑰D(供軟件註冊模板和註冊機使用);
2. 用戶安裝軟件後,軟件註冊模板提取用戶機器指紋信息(如:MAC地址、CPU序列號、硬盤序列號等),並經過其它的編碼算法(如BASE64)生成一個申請碼C;
3. 用戶將申請碼C發給軟件開發商。軟件開發商經過註冊機採用私鑰D加密申請碼C後生成激活碼F。軟件供應商將激活碼F發給用戶。
4. 用戶輸入激活碼F,軟件註冊模板採用公鑰E對激活碼F解碼後生成G(即:用戶機器特徵信息),而後軟件註冊模板提取用戶機器的特定信息後進行編碼。將編碼的結果與G進行比較,若是相等則用戶合法,完成受權,不然受權失敗。
- public partial class Form1 : Form
- {
-
- public Form1()
- {
- InitializeComponent();
- }
-
- private void Form1_Load(object sender, EventArgs e)
- {
- string cpu = RSAHelper.GetCpuID();
- string _申請碼C = RSAHelper.EncodeBase64("utf-8", cpu);
- textEdit申請碼.Text = _申請碼C;
- }
-
- private void simpleButton註冊_Click(object sender, EventArgs e)
- {
- string publicKeyPath = @"C://PublicKey.xml";
- RSAParameters pm = RSAHelper.ReadKey(false, publicKeyPath);
-
- string _PublicKey = RSAHelper.ComponentKey(pm.Exponent, pm.Modulus);
-
- string cpu = RSAHelper.DecryptString(textEdit激活碼.Text, _PublicKey);
- if (cpu == textEdit申請碼.Text)
- {
- MessageBox.Show("註冊成功");
- }
- else
- {
- MessageBox.Show("註冊失敗");
- }
- }
- }
-
-
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
-
- private void simpleButton生成激活碼_Click(object sender, EventArgs e)
- {
- string privateKeyPath = @"C://PrivateKey.xml";
- RSAParameters pm = RSAHelper.ReadKey(true, privateKeyPath);
- string _PrivateKey = RSAHelper.ComponentKey(pm.D, pm.Modulus);
- textEdit激活碼.Text = RSAHelper.EncryptString(textEdit申請碼.Text, _PrivateKey);
- }
- }