RSA不對稱加密,公鑰加密私鑰解密,私鑰加密公鑰解密

 

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 結構中函數

 

[csharp]  view plaincopy
  1. //Generate a public/private key pair.  
  2. RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();  
  3. //Save the public key information to an RSAParameters structure.  
  4. RSAParameters RSAKeyInfo = RSA.ExportParameters(false);  

 

 

1、公鑰加密私鑰解密

[csharp]  view plaincopy
  1. /// <summary>  
  2.    /// 公鑰加密,私鑰解密  
  3.    /// </summary>  
  4.    public class RSAEncryptHelper  
  5.    {  
  6.   
  7.        /// <summary>  
  8.        /// 將字符串使用base64算法加密  
  9.        /// </summary>  
  10.        /// <param name="code_type">編碼類型</param>  
  11.        /// <param name="code">待加密的字符串</param>  
  12.        /// <returns>加密後的字符串</returns>        
  13.        public string EncodeBase64(string code_type, string code)  
  14.        {  
  15.            string encode = "";  
  16.            byte[] bytes = Encoding.GetEncoding(code_type).GetBytes(code); //將一組字符編碼爲一個字節序列.  
  17.            try  
  18.            {  
  19.                encode = Convert.ToBase64String(bytes); //將8位無符號整數數組的子集轉換爲其等效的,以64爲基的數字編碼的字符串形式.  
  20.            }  
  21.            catch  
  22.            {  
  23.                encode = code;  
  24.            }  
  25.            return encode;  
  26.        }  
  27.   
  28.        /// <summary>  
  29.        /// 將字符串使用base64算法解密  
  30.        /// </summary>  
  31.        /// <param name="code_type">編碼類型</param>  
  32.        /// <param name="code">已用base64算法加密的字符串</param>  
  33.        /// <returns>解密後的字符串</returns>  
  34.        public string DecodeBase64(string code_type, string code)  
  35.        {  
  36.   
  37.            string decode = "";  
  38.            byte[] bytes = Convert.FromBase64String(code); //將2進制編碼轉換爲8位無符號整數數組.  
  39.            try  
  40.            {  
  41.                decode = Encoding.GetEncoding(code_type).GetString(bytes); //將指定字節數組中的一個字節序列解碼爲一個字符串。  
  42.            }  
  43.            catch  
  44.            {  
  45.                decode = code;  
  46.            }  
  47.            return decode;  
  48.        }  
  49.        /// <summary>  
  50.        /// 獲取本機的MAC地址  
  51.        /// </summary>  
  52.        /// <returns></returns>  
  53.        public static string GetLocalMac()  
  54.        {  
  55.            string mac = null;  
  56.            ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");  
  57.            ManagementObjectCollection queryCollection = query.Get();  
  58.            foreach (ManagementObject mo in queryCollection)  
  59.            {  
  60.                if (mo["IPEnabled"].ToString() == "True")  
  61.                    mac = mo["MacAddress"].ToString();  
  62.            }  
  63.            return (mac);  
  64.        }  
  65.   
  66.        /// <summary>  
  67.        /// 獲得CPU序列號  
  68.        /// </summary>  
  69.        /// <returns></returns>  
  70.        public static string GetCpuID()  
  71.        {  
  72.            try  
  73.            {  
  74.                //獲取CPU序列號代碼   
  75.                string cpuInfo = "";//cpu序列號   
  76.                ManagementClass mc = new ManagementClass("Win32_Processor");  
  77.                ManagementObjectCollection moc = mc.GetInstances();  
  78.                foreach (ManagementObject mo in moc)  
  79.                {  
  80.                    cpuInfo = mo.Properties["ProcessorId"].Value.ToString();  
  81.                }  
  82.                moc = null;  
  83.                mc = null;  
  84.                return cpuInfo;  
  85.            }  
  86.            catch  
  87.            {  
  88.                return "unknow";  
  89.            }  
  90.            finally  
  91.            {  
  92.            }  
  93.   
  94.        }  
  95.        /// <summary>  
  96.   
  97.        /// 生成公私鑰  
  98.   
  99.        /// </summary>  
  100.   
  101.        /// <param name="PrivateKeyPath"></param>  
  102.   
  103.        /// <param name="PublicKeyPath"></param>  
  104.   
  105.        public void RSAKey(string PrivateKeyPath, string PublicKeyPath)  
  106.        {  
  107.   
  108.            try  
  109.            {  
  110.   
  111.                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();  
  112.   
  113.                this.CreatePrivateKeyXML(PrivateKeyPath, provider.ToXmlString(true));  
  114.   
  115.                this.CreatePublicKeyXML(PublicKeyPath, provider.ToXmlString(false));  
  116.   
  117.            }  
  118.   
  119.            catch (Exception exception)  
  120.            {  
  121.   
  122.                throw exception;  
  123.   
  124.            }  
  125.   
  126.        }  
  127.   
  128.        /// <summary>  
  129.   
  130.        /// 對原始數據進行MD5加密  
  131.   
  132.        /// </summary>  
  133.   
  134.        /// <param name="m_strSource">待加密數據</param>  
  135.   
  136.        /// <returns>返回機密後的數據</returns>  
  137.   
  138.        public string GetHash(string m_strSource)  
  139.        {  
  140.   
  141.            HashAlgorithm algorithm = HashAlgorithm.Create("MD5");  
  142.   
  143.            byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(m_strSource);  
  144.   
  145.            byte[] inArray = algorithm.ComputeHash(bytes);  
  146.   
  147.            return Convert.ToBase64String(inArray);  
  148.   
  149.        }  
  150.   
  151.        /// <summary>  
  152.   
  153.        /// RSA加密  
  154.   
  155.        /// </summary>  
  156.   
  157.        /// <param name="xmlPublicKey">公鑰</param>  
  158.   
  159.        /// <param name="m_strEncryptString">MD5加密後的數據</param>  
  160.   
  161.        /// <returns>RSA公鑰加密後的數據</returns>  
  162.   
  163.        public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)  
  164.        {  
  165.   
  166.            string str2;  
  167.   
  168.            try  
  169.            {  
  170.   
  171.                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();  
  172.   
  173.                provider.FromXmlString(xmlPublicKey);  
  174.                 
  175.                byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);  
  176.   
  177.                str2 = Convert.ToBase64String(provider.Encrypt(bytes, false));  
  178.   
  179.            }  
  180.   
  181.            catch (Exception exception)  
  182.            {  
  183.   
  184.                throw exception;  
  185.   
  186.            }  
  187.   
  188.            return str2;  
  189.   
  190.        }  
  191.   
  192.        /// <summary>  
  193.   
  194.        /// RSA解密  
  195.   
  196.        /// </summary>  
  197.   
  198.        /// <param name="xmlPrivateKey">私鑰</param>  
  199.   
  200.        /// <param name="m_strDecryptString">待解密的數據</param>  
  201.   
  202.        /// <returns>解密後的結果</returns>  
  203.   
  204.        public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)  
  205.        {  
  206.   
  207.            string str2;  
  208.   
  209.            try  
  210.            {  
  211.   
  212.                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();  
  213.   
  214.                provider.FromXmlString(xmlPrivateKey);  
  215.   
  216.                byte[] rgb = Convert.FromBase64String(m_strDecryptString);  
  217.   
  218.                byte[] buffer2 = provider.Decrypt(rgb, false);  
  219.   
  220.                str2 = new UnicodeEncoding().GetString(buffer2);  
  221.   
  222.            }  
  223.            catch (Exception exception)  
  224.            {  
  225.   
  226.                throw exception;  
  227.   
  228.            }  
  229.   
  230.            return str2;  
  231.   
  232.        }  
  233.   
  234.        /// <summary>  
  235.   
  236.        /// 對MD5加密後的密文進行簽名  
  237.   
  238.        /// </summary>  
  239.   
  240.        /// <param name="p_strKeyPrivate">私鑰</param>  
  241.   
  242.        /// <param name="m_strHashbyteSignature">MD5加密後的密文</param>  
  243.   
  244.        /// <returns></returns>  
  245.   
  246.        public string SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature)  
  247.        {  
  248.   
  249.            byte[] rgbHash = Convert.FromBase64String(m_strHashbyteSignature);  
  250.   
  251.            RSACryptoServiceProvider key = new RSACryptoServiceProvider();  
  252.   
  253.            key.FromXmlString(p_strKeyPrivate);  
  254.   
  255.            RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);  
  256.   
  257.            formatter.SetHashAlgorithm("MD5");  
  258.   
  259.            byte[] inArray = formatter.CreateSignature(rgbHash);  
  260.   
  261.            return Convert.ToBase64String(inArray);  
  262.   
  263.        }  
  264.   
  265.        /// <summary>  
  266.   
  267.        /// 簽名驗證  
  268.   
  269.        /// </summary>  
  270.   
  271.        /// <param name="p_strKeyPublic">公鑰</param>  
  272.   
  273.        /// <param name="p_strHashbyteDeformatter">待驗證的用戶名</param>  
  274.   
  275.        /// <param name="p_strDeformatterData">註冊碼</param>  
  276.   
  277.        /// <returns></returns>  
  278.   
  279.        public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData)  
  280.        {  
  281.   
  282.            try  
  283.            {  
  284.   
  285.                byte[] rgbHash = Convert.FromBase64String(p_strHashbyteDeformatter);  
  286.   
  287.                RSACryptoServiceProvider key = new RSACryptoServiceProvider();  
  288.   
  289.                key.FromXmlString(p_strKeyPublic);  
  290.   
  291.                RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);  
  292.   
  293.                deformatter.SetHashAlgorithm("MD5");  
  294.   
  295.                byte[] rgbSignature = Convert.FromBase64String(p_strDeformatterData);  
  296.   
  297.                if (deformatter.VerifySignature(rgbHash, rgbSignature))  
  298.                {  
  299.   
  300.                    return true;  
  301.   
  302.                }  
  303.   
  304.                return false;  
  305.   
  306.            }  
  307.   
  308.            catch  
  309.            {  
  310.   
  311.                return false;  
  312.   
  313.            }  
  314.   
  315.        }  
  316.   
  317.        /// <summary>  
  318.   
  319.        /// 獲取硬盤ID  
  320.   
  321.        /// </summary>  
  322.   
  323.        /// <returns>硬盤ID</returns>  
  324.   
  325.        public string GetHardID()  
  326.        {  
  327.   
  328.            string HDInfo = "";  
  329.   
  330.            ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");  
  331.   
  332.            ManagementObjectCollection moc1 = cimobject1.GetInstances();  
  333.   
  334.            foreach (ManagementObject mo in moc1)  
  335.            {  
  336.   
  337.                HDInfo = (string)mo.Properties["Model"].Value;  
  338.   
  339.            }  
  340.   
  341.            return HDInfo;  
  342.   
  343.        }  
  344.   
  345.        /// <summary>  
  346.   
  347.        /// 讀註冊表中指定鍵的值  
  348.   
  349.        /// </summary>  
  350.   
  351.        /// <param name="key">鍵名</param>  
  352.   
  353.        /// <returns>返回鍵值</returns>  
  354.   
  355.        private string ReadReg(string key)  
  356.        {  
  357.   
  358.            string temp = "";  
  359.   
  360.            try  
  361.            {  
  362.   
  363.                RegistryKey myKey = Registry.LocalMachine;  
  364.   
  365.                RegistryKey subKey = myKey.OpenSubKey(@"SOFTWARE/JX/Register");  
  366.   
  367.   
  368.   
  369.                temp = subKey.GetValue(key).ToString();  
  370.   
  371.                subKey.Close();  
  372.   
  373.                myKey.Close();  
  374.   
  375.                return temp;  
  376.   
  377.            }  
  378.   
  379.            catch (Exception)  
  380.            {  
  381.   
  382.                throw;//可能沒有此註冊項;  
  383.   
  384.            }  
  385.   
  386.   
  387.   
  388.        }  
  389.   
  390.        /// <summary>  
  391.   
  392.        /// 建立註冊表中指定的鍵和值  
  393.   
  394.        /// </summary>  
  395.   
  396.        /// <param name="key">鍵名</param>  
  397.   
  398.        /// <param name="value">鍵值</param>  
  399.   
  400.        private void WriteReg(string key, string value)  
  401.        {  
  402.   
  403.            try  
  404.            {  
  405.   
  406.                RegistryKey rootKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");  
  407.   
  408.                rootKey.SetValue(key, value);  
  409.   
  410.                rootKey.Close();  
  411.   
  412.            }  
  413.   
  414.            catch (Exception)  
  415.            {  
  416.   
  417.                throw;  
  418.   
  419.            }  
  420.   
  421.        }  
  422.   
  423.        /// <summary>  
  424.   
  425.        /// 建立公鑰文件  
  426.   
  427.        /// </summary>  
  428.   
  429.        /// <param name="path"></param>  
  430.   
  431.        /// <param name="publickey"></param>  
  432.   
  433.        public void CreatePublicKeyXML(string path, string publickey)  
  434.        {  
  435.   
  436.            try  
  437.            {  
  438.   
  439.                FileStream publickeyxml = new FileStream(path, FileMode.Create);  
  440.   
  441.                StreamWriter sw = new StreamWriter(publickeyxml);  
  442.   
  443.                sw.WriteLine(publickey);  
  444.   
  445.                sw.Close();  
  446.   
  447.                publickeyxml.Close();  
  448.   
  449.            }  
  450.   
  451.            catch  
  452.            {  
  453.   
  454.                throw;  
  455.   
  456.            }  
  457.   
  458.        }  
  459.   
  460.        /// <summary>  
  461.   
  462.        /// 建立私鑰文件  
  463.   
  464.        /// </summary>  
  465.   
  466.        /// <param name="path"></param>  
  467.   
  468.        /// <param name="privatekey"></param>  
  469.   
  470.        public void CreatePrivateKeyXML(string path, string privatekey)  
  471.        {  
  472.   
  473.            try  
  474.            {  
  475.   
  476.                FileStream privatekeyxml = new FileStream(path, FileMode.Create);  
  477.   
  478.                StreamWriter sw = new StreamWriter(privatekeyxml);  
  479.   
  480.                sw.WriteLine(privatekey);  
  481.   
  482.                sw.Close();  
  483.   
  484.                privatekeyxml.Close();  
  485.   
  486.            }  
  487.   
  488.            catch  
  489.            {  
  490.   
  491.                throw;  
  492.   
  493.            }  
  494.   
  495.        }  
  496.   
  497.        /// <summary>  
  498.   
  499.        /// 讀取公鑰  
  500.   
  501.        /// </summary>  
  502.   
  503.        /// <param name="path"></param>  
  504.   
  505.        /// <returns></returns>  
  506.   
  507.        public string ReadPublicKey(string path)  
  508.        {  
  509.   
  510.            StreamReader reader = new StreamReader(path);  
  511.   
  512.            string publickey = reader.ReadToEnd();  
  513.   
  514.            reader.Close();  
  515.   
  516.            return publickey;  
  517.   
  518.        }  
  519.   
  520.        /// <summary>  
  521.   
  522.        /// 讀取私鑰  
  523.   
  524.        /// </summary>  
  525.   
  526.        /// <param name="path"></param>  
  527.   
  528.        /// <returns></returns>  
  529.   
  530.        public string ReadPrivateKey(string path)  
  531.        {  
  532.   
  533.            StreamReader reader = new StreamReader(path);  
  534.   
  535.            string privatekey = reader.ReadToEnd();  
  536.   
  537.            reader.Close();  
  538.   
  539.            return privatekey;  
  540.   
  541.        }  
  542.   
  543.        /// <summary>  
  544.   
  545.        /// 初始化註冊表,程序運行時調用,在調用以前更新公鑰xml  
  546.   
  547.        /// </summary>  
  548.   
  549.        /// <param name="path">公鑰路徑</param>  
  550.   
  551.        public void InitialReg(string path)  
  552.        {  
  553.   
  554.            Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");  
  555.   
  556.            Random ra = new Random();  
  557.   
  558.            string publickey = this.ReadPublicKey(path);  
  559.   
  560.            if (Registry.LocalMachine.OpenSubKey(@"SOFTWARE/JX/Register").ValueCount <= 0)  
  561.            {  
  562.   
  563.                this.WriteReg("RegisterRandom", ra.Next(1, 100000).ToString());  
  564.   
  565.                this.WriteReg("RegisterPublicKey", publickey);  
  566.   
  567.            }  
  568.   
  569.            else  
  570.            {  
  571.   
  572.                this.WriteReg("RegisterPublicKey", publickey);  
  573.   
  574.            }  
  575.   
  576.        }   
  577.    }  

 

2、私鑰加密公鑰解密

 

[csharp]  view plaincopy
  1. /// <summary>  
  2.    /// 非對稱RSA加密類 能夠參考  
  3.    /// http://www.cnblogs.com/hhh/archive/2011/06/03/2070692.html  
  4.    /// http://blog.csdn.net/zhilunchen/article/details/2943158  
  5.    /// http://www.cnblogs.com/yyl8781697/archive/2013/04/28/RSA.html  
  6.    /// 如果私匙加密 則需公鑰解密  
  7.    /// 反正公鑰加密 私匙來解密  
  8.    /// 須要BigInteger類來輔助  
  9.    /// </summary>  
  10.    public static class RSAHelper  
  11.    {  
  12.        /// <summary>  
  13.        /// RSA的容器 能夠解密的源字符串長度爲 DWKEYSIZE/8-11   
  14.        /// </summary>  
  15.        public const int DWKEYSIZE = 1024;  
  16.   
  17.        /// <summary>  
  18.        /// RSA加密的密匙結構  公鑰和私匙  
  19.        /// </summary>  
  20.        //public struct RSAKey  
  21.        //{  
  22.        //    public string PublicKey { get; set; }  
  23.        //    public string PrivateKey { get; set; }  
  24.        //}  
  25.  
  26.        #region 獲得RSA的解謎的密匙對  
  27.        /// <summary>  
  28.        /// 獲得RSA的解謎的密匙對  
  29.        /// </summary>  
  30.        /// <returns></returns>  
  31.        //public static RSAKey GetRASKey()  
  32.        //{  
  33.        //    RSACryptoServiceProvider.UseMachineKeyStore = true;  
  34.        //    //聲明一個指定大小的RSA容器  
  35.        //    RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(DWKEYSIZE);  
  36.        //    //取得RSA容易裏的各類參數  
  37.        //    RSAParameters p = rsaProvider.ExportParameters(true);  
  38.   
  39.        //    return new RSAKey()  
  40.        //    {  
  41.        //        PublicKey = ComponentKey(p.Exponent, p.Modulus),  
  42.        //        PrivateKey = ComponentKey(p.D, p.Modulus)  
  43.        //    };  
  44.        //}  
  45.        #endregion  
  46.  
  47.        #region 檢查明文的有效性 DWKEYSIZE/8-11 長度以內爲有效 中英文都算一個字符  
  48.        /// <summary>  
  49.        /// 檢查明文的有效性 DWKEYSIZE/8-11 長度以內爲有效 中英文都算一個字符  
  50.        /// </summary>  
  51.        /// <param name="source"></param>  
  52.        /// <returns></returns>  
  53.        public static bool CheckSourceValidate(string source)  
  54.        {  
  55.            return (DWKEYSIZE / 8 - 11) >= source.Length;  
  56.        }  
  57.        #endregion  
  58.  
  59.        #region 組合解析密匙  
  60.        /// <summary>  
  61.        /// 組合成密匙字符串  
  62.        /// </summary>  
  63.        /// <param name="b1"></param>  
  64.        /// <param name="b2"></param>  
  65.        /// <returns></returns>  
  66.        public static string ComponentKey(byte[] b1, byte[] b2)  
  67.        {  
  68.            List<byte> list = new List<byte>();  
  69.            //在前端加上第一個數組的長度值 這樣從此能夠根據這個值分別取出來兩個數組  
  70.            list.Add((byte)b1.Length);  
  71.            list.AddRange(b1);  
  72.            list.AddRange(b2);  
  73.            byte[] b = list.ToArray<byte>();  
  74.            return Convert.ToBase64String(b);  
  75.        }  
  76.   
  77.        /// <summary>  
  78.        /// 解析密匙  
  79.        /// </summary>  
  80.        /// <param name="key">密匙</param>  
  81.        /// <param name="b1">RSA的相應參數1</param>  
  82.        /// <param name="b2">RSA的相應參數2</param>  
  83.        private static void ResolveKey(string key, out byte[] b1, out byte[] b2)  
  84.        {  
  85.            //從base64字符串 解析成原來的字節數組  
  86.            byte[] b = Convert.FromBase64String(key);  
  87.            //初始化參數的數組長度  
  88.            b1 = new byte[b[0]];  
  89.            b2 = new byte[b.Length - b[0] - 1];  
  90.            //將相應位置是值放進相應的數組  
  91.            for (int n = 1, i = 0, j = 0; n < b.Length; n++)  
  92.            {  
  93.                if (n <= b[0])  
  94.                {  
  95.                    b1[i++] = b[n];  
  96.                }  
  97.                else  
  98.                {  
  99.                    b2[j++] = b[n];  
  100.                }  
  101.            }  
  102.        }  
  103.        #endregion  
  104.  
  105.        #region 字符串加密解密 公開方法  
  106.        /// <summary>  
  107.        /// 字符串加密  
  108.        /// </summary>  
  109.        /// <param name="source">源字符串 明文</param>  
  110.        /// <param name="key">密匙</param>  
  111.        /// <returns>加密遇到錯誤將會返回原字符串</returns>  
  112.        public static string EncryptString(string source, string key)  
  113.        {  
  114.            string encryptString = string.Empty;  
  115.            byte[] d;  
  116.            byte[] n;  
  117.            try  
  118.            {  
  119.                if (!CheckSourceValidate(source))  
  120.                {  
  121.                    throw new Exception("source string too long");  
  122.                }  
  123.                //解析這個密鑰  
  124.                ResolveKey(key, out d, out n);  
  125.                BigInteger biN = new BigInteger(n);  
  126.                BigInteger biD = new BigInteger(d);  
  127.                encryptString = EncryptString(source, biD, biN);  
  128.            }  
  129.            catch  
  130.            {  
  131.                encryptString = source;  
  132.            }  
  133.            return encryptString;  
  134.        }  
  135.   
  136.        /// <summary>  
  137.        /// 字符串解密  
  138.        /// </summary>  
  139.        /// <param name="encryptString">密文</param>  
  140.        /// <param name="key">密鑰</param>  
  141.        /// <returns>遇到解密失敗將會返回空字符串</returns>  
  142.        public static string DecryptString(string encryptString, string key)  
  143.        {  
  144.            string source = string.Empty;  
  145.            byte[] e;  
  146.            byte[] n;  
  147.            try  
  148.            {  
  149.                //解析這個密鑰  
  150.                ResolveKey(key, out e, out n);  
  151.                BigInteger biE = new BigInteger(e);  
  152.                BigInteger biN = new BigInteger(n);  
  153.                source = DecryptString(encryptString, biE, biN);  
  154.            }  
  155.            catch  
  156.            {  
  157.            }  
  158.            return source;  
  159.        }  
  160.        #endregion  
  161.  
  162.        #region 字符串加密解密 私有  實現加解密的實現方法  
  163.        /// <summary>  
  164.        /// 用指定的密匙加密   
  165.        /// </summary>  
  166.        /// <param name="source">明文</param>  
  167.        /// <param name="d">能夠是RSACryptoServiceProvider生成的D</param>  
  168.        /// <param name="n">能夠是RSACryptoServiceProvider生成的Modulus</param>  
  169.        /// <returns>返回密文</returns>  
  170.        private static string EncryptString(string source, BigInteger d, BigInteger n)  
  171.        {  
  172.            int len = source.Length;  
  173.            int len1 = 0;  
  174.            int blockLen = 0;  
  175.            if ((len % 128) == 0)  
  176.                len1 = len / 128;  
  177.            else  
  178.                len1 = len / 128 + 1;  
  179.            string block = "";  
  180.            StringBuilder result = new StringBuilder();  
  181.            for (int i = 0; i < len1; i++)  
  182.            {  
  183.                if (len >= 128)  
  184.                    blockLen = 128;  
  185.                else  
  186.                    blockLen = len;  
  187.                block = source.Substring(i * 128, blockLen);  
  188.                byte[] oText = System.Text.Encoding.Default.GetBytes(block);  
  189.                BigInteger biText = new BigInteger(oText);  
  190.                BigInteger biEnText = biText.modPow(d, n);  
  191.                string temp = biEnText.ToHexString();  
  192.                result.Append(temp).Append("@");  
  193.                len -= blockLen;  
  194.            }  
  195.            return result.ToString().TrimEnd('@');  
  196.        }  
  197.   
  198.        /// <summary>  
  199.        /// 用指定的密匙加密   
  200.        /// </summary>  
  201.        /// <param name="source">密文</param>  
  202.        /// <param name="e">能夠是RSACryptoServiceProvider生成的Exponent</param>  
  203.        /// <param name="n">能夠是RSACryptoServiceProvider生成的Modulus</param>  
  204.        /// <returns>返回明文</returns>  
  205.        private static string DecryptString(string encryptString, BigInteger e, BigInteger n)  
  206.        {  
  207.            StringBuilder result = new StringBuilder();  
  208.            string[] strarr1 = encryptString.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);  
  209.            for (int i = 0; i < strarr1.Length; i++)  
  210.            {  
  211.                string block = strarr1[i];  
  212.                BigInteger biText = new BigInteger(block, 16);  
  213.                BigInteger biEnText = biText.modPow(e, n);  
  214.                string temp = System.Text.Encoding.Default.GetString(biEnText.getBytes());  
  215.                result.Append(temp);  
  216.            }  
  217.            return result.ToString();  
  218.        }  
  219.        #endregion  
  220.   
  221.   
  222.        /// <summary>  
  223.        /// 將字符串使用base64算法加密  
  224.        /// </summary>  
  225.        /// <param name="code_type">編碼類型</param>  
  226.        /// <param name="code">待加密的字符串</param>  
  227.        /// <returns>加密後的字符串</returns>        
  228.        public static string EncodeBase64(string code_type, string code)  
  229.        {  
  230.            string encode = "";  
  231.            byte[] bytes = Encoding.GetEncoding(code_type).GetBytes(code); //將一組字符編碼爲一個字節序列.  
  232.            try  
  233.            {  
  234.                encode = Convert.ToBase64String(bytes); //將8位無符號整數數組的子集轉換爲其等效的,以64爲基的數字編碼的字符串形式.  
  235.            }  
  236.            catch  
  237.            {  
  238.                encode = code;  
  239.            }  
  240.            return encode;  
  241.        }  
  242.   
  243.        /// <summary>  
  244.        /// 將字符串使用base64算法解密  
  245.        /// </summary>  
  246.        /// <param name="code_type">編碼類型</param>  
  247.        /// <param name="code">已用base64算法加密的字符串</param>  
  248.        /// <returns>解密後的字符串</returns>  
  249.        public static string DecodeBase64(string code_type, string code)  
  250.        {  
  251.   
  252.            string decode = "";  
  253.            byte[] bytes = Convert.FromBase64String(code); //將2進制編碼轉換爲8位無符號整數數組.  
  254.            try  
  255.            {  
  256.                decode = Encoding.GetEncoding(code_type).GetString(bytes); //將指定字節數組中的一個字節序列解碼爲一個字符串。  
  257.            }  
  258.            catch  
  259.            {  
  260.                decode = code;  
  261.            }  
  262.            return decode;  
  263.        }  
  264.          
  265.        /// <summary>  
  266.        /// 讀取公鑰或私鑰  
  267.        /// </summary>  
  268.        /// <param name="includePrivateparameters">爲True則包含私鑰</param>  
  269.        /// <param name="path">Xml格式保存的完整公/私鑰路徑</param>  
  270.        /// <returns>公鑰或私鑰參數形式 </returns>  
  271.        public static RSAParameters ReadKey(bool includePrivateparameters,string path)  
  272.        {  
  273.            using (StreamReader reader = new StreamReader(path))  
  274.            {  
  275.                string publickey = reader.ReadToEnd();  
  276.                RSACryptoServiceProvider rcp = new RSACryptoServiceProvider();  
  277.                rcp.FromXmlString(publickey);  
  278.                return rcp.ExportParameters(includePrivateparameters);  
  279.            }  
  280.        }  
  281.   
  282.        /// <summary>  
  283.        /// 獲取本機的MAC地址  
  284.        /// </summary>  
  285.        /// <returns></returns>  
  286.        public static string GetLocalMac()  
  287.        {  
  288.            string mac = null;  
  289.            ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");  
  290.            ManagementObjectCollection queryCollection = query.Get();  
  291.            foreach (ManagementObject mo in queryCollection)  
  292.            {  
  293.                if (mo["IPEnabled"].ToString() == "True")  
  294.                    mac = mo["MacAddress"].ToString();  
  295.            }  
  296.            return (mac);  
  297.        }  
  298.   
  299.        /// <summary>  
  300.        /// 獲得CPU序列號  
  301.        /// </summary>  
  302.        /// <returns></returns>  
  303.        public static string GetCpuID()  
  304.        {  
  305.            try  
  306.            {  
  307.                //獲取CPU序列號代碼   
  308.                string cpuInfo = "";//cpu序列號   
  309.                ManagementClass mc = new ManagementClass("Win32_Processor");  
  310.                ManagementObjectCollection moc = mc.GetInstances();  
  311.                foreach (ManagementObject mo in moc)  
  312.                {  
  313.                    cpuInfo = mo.Properties["ProcessorId"].Value.ToString();  
  314.                }  
  315.                moc = null;  
  316.                mc = null;  
  317.                return cpuInfo;  
  318.            }  
  319.            catch  
  320.            {  
  321.                return "unknow";  
  322.            }  
  323.            finally  
  324.            {  
  325.            }  
  326.   
  327.        }  
  328.   
  329.        /// <summary>  
  330.   
  331.        /// 獲取硬盤ID  
  332.   
  333.        /// </summary>  
  334.   
  335.        /// <returns>硬盤ID</returns>  
  336.   
  337.        public static string GetHardID()  
  338.        {  
  339.   
  340.            string HDInfo = "";  
  341.   
  342.            ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");  
  343.   
  344.            ManagementObjectCollection moc1 = cimobject1.GetInstances();  
  345.   
  346.            foreach (ManagementObject mo in moc1)  
  347.            {  
  348.   
  349.                HDInfo = (string)mo.Properties["Model"].Value;  
  350.   
  351.            }  
  352.   
  353.            return HDInfo;  
  354.   
  355.        }  
  356.   
  357.        /// <summary>  
  358.   
  359.        /// 讀註冊表中指定鍵的值  
  360.   
  361.        /// </summary>  
  362.   
  363.        /// <param name="key">鍵名</param>  
  364.   
  365.        /// <returns>返回鍵值</returns>  
  366.   
  367.        private static string ReadReg(string key)  
  368.        {  
  369.   
  370.            string temp = "";  
  371.   
  372.            try  
  373.            {  
  374.   
  375.                RegistryKey myKey = Registry.LocalMachine;  
  376.   
  377.                RegistryKey subKey = myKey.OpenSubKey(@"SOFTWARE/JX/Register");  
  378.   
  379.   
  380.   
  381.                temp = subKey.GetValue(key).ToString();  
  382.   
  383.                subKey.Close();  
  384.   
  385.                myKey.Close();  
  386.   
  387.                return temp;  
  388.   
  389.            }  
  390.   
  391.            catch (Exception)  
  392.            {  
  393.   
  394.                throw;//可能沒有此註冊項;  
  395.   
  396.            }  
  397.        }  
  398.   
  399.        /// <summary>  
  400.   
  401.        /// 建立註冊表中指定的鍵和值  
  402.   
  403.        /// </summary>  
  404.   
  405.        /// <param name="key">鍵名</param>  
  406.   
  407.        /// <param name="value">鍵值</param>  
  408.   
  409.        private static void WriteReg(string key, string value)  
  410.        {  
  411.            try  
  412.            {  
  413.   
  414.                RegistryKey rootKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");  
  415.   
  416.                rootKey.SetValue(key, value);  
  417.   
  418.                rootKey.Close();  
  419.   
  420.            }  
  421.   
  422.            catch (Exception)  
  423.            {  
  424.   
  425.                throw;  
  426.   
  427.            }  
  428.   
  429.        }  
  430.   
  431.         
  432.    }  

 

使用場景:如共享軟件加密,咱們須要用私鑰加密註冊碼或註冊文件,發給用戶,用戶用公鑰解密註冊碼或註冊文件進行合法性驗證。

RSA算法實現激活碼註冊方式的原理以下:

1. 生成一對公鑰E和私鑰D(供軟件註冊模板和註冊機使用);

2. 用戶安裝軟件後,軟件註冊模板提取用戶機器指紋信息(如:MAC地址、CPU序列號、硬盤序列號等),並經過其它的編碼算法(如BASE64)生成一個申請碼C;

3. 用戶將申請碼C發給軟件開發商。軟件開發商經過註冊機採用私鑰D加密申請碼C後生成激活碼F。軟件供應商將激活碼F發給用戶。

4. 用戶輸入激活碼F,軟件註冊模板採用公鑰E對激活碼F解碼後生成G(即:用戶機器特徵信息),而後軟件註冊模板提取用戶機器的特定信息後進行編碼。將編碼的結果與G進行比較,若是相等則用戶合法,完成受權,不然受權失敗。

 

[csharp]  view plaincopy
  1. //應用程序註冊模塊  
  2.    public partial class Form1 : Form  
  3.    {  
  4.         
  5.        public Form1()  
  6.        {  
  7.            InitializeComponent();  
  8.        }  
  9.   
  10.        private void Form1_Load(object sender, EventArgs e)  
  11.        {  
  12.            string cpu = RSAHelper.GetCpuID();  
  13.            string _申請碼C = RSAHelper.EncodeBase64("utf-8", cpu);  
  14.            textEdit申請碼.Text = _申請碼C;  
  15.        }  
  16.   
  17.        private void simpleButton註冊_Click(object sender, EventArgs e)  
  18.        {  
  19.            string publicKeyPath = @"C://PublicKey.xml";  
  20.            RSAParameters pm = RSAHelper.ReadKey(false, publicKeyPath);  
  21.   
  22.            string _PublicKey = RSAHelper.ComponentKey(pm.Exponent, pm.Modulus);  
  23.   
  24.            string cpu = RSAHelper.DecryptString(textEdit激活碼.Text, _PublicKey);  
  25.            if (cpu == textEdit申請碼.Text)  
  26.            {  
  27.                MessageBox.Show("註冊成功");  
  28.            }  
  29.            else  
  30.            {  
  31.                MessageBox.Show("註冊失敗");  
  32.            }  
  33.        }  
  34.    }  

 

[csharp]  view plaincopy
    1. /// <summary>  
    2.    /// 註冊機  
    3.    /// </summary>  
    4.    public partial class Form1 : Form  
    5.    {  
    6.        public Form1()  
    7.        {  
    8.            InitializeComponent();  
    9.        }  
    10.        
    11.        private void simpleButton生成激活碼_Click(object sender, EventArgs e)  
    12.        {  
    13.            string privateKeyPath = @"C://PrivateKey.xml";  
    14.            RSAParameters pm = RSAHelper.ReadKey(true, privateKeyPath);  
    15.            string _PrivateKey = RSAHelper.ComponentKey(pm.D, pm.Modulus);  
    16.            textEdit激活碼.Text = RSAHelper.EncryptString(textEdit申請碼.Text, _PrivateKey);  
    17.        }  
    18.    } 
相關文章
相關標籤/搜索