zoukankan      html  css  js  c++  java
  • RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。

    .NET提供常用的加密算法类,支持RSA的类是RSACryptoServiceProvider(命名空间:System.Security.Cryptography),但只支持公钥加密,私钥解密。RSACryptoServiceProvider类包括:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D等8个属性,其中Modulus和Exponent就是公钥,Modulus和D就是私钥,RSACryptoServiceProvider类提供导出公钥的方法,也提供导出私钥的方法,但导出的私钥包含上面8个属性,显然要用RSACryptoServiceProvider实现私钥加密公钥是不可行的。

        从RSA的原理来看,公钥加密私钥解密和私钥加密公钥解密应该是等价的,在某些情况下,比如共享软件加密,我们需要用私钥加密注册码或注册文件,发给用户,用户用公钥解密注册码或注册文件进行合法性验证。

    不对称密钥

    .NET Framework 为不对称加密提供了 RSACryptoServiceProvider 和 DSACryptoServiceProvider 类。这些类在您使用默认构造函数创建新实例时创建一个公钥/私钥对。既可以存储不对称密钥以用在多个会话中,也可以只为一个会话生成不对称密钥。公钥可以被广泛地使用,私钥应被严密地保护起来。

    每当创建不对称算法类的新实例时,都生成一个公钥/私钥对。创建该类的新实例后,可以用以下两种方法之一提取密钥信息:

    两个方法都接受布尔值,该值指示是只返回公钥信息还是同时返回公钥和私钥信息。通过使用 ImportParameters 方法,可以将 RSACryptoServiceProvider 类初始化为 RSAParameters 结构的值。

    下面的代码示例创建 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);  

    一、公钥加密私钥解密

    [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.    }  

    二、私钥加密公钥解密

    [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.    } 
  • 相关阅读:
    java pojo类
    web(一)
    java通过配置文件(Properties类)连接Oracle数据库代码示例
    java数组排序(插入排序、冒泡排序、选择排序)与递归 代码示例
    匿名内部类
    java反射机制
    ubuntu安装kvm流程
    squid代理服务问答
    ftp nfs samba比较
    Samba服务问答
  • 原文地址:https://www.cnblogs.com/zhangruisoldier/p/4644582.html
Copyright © 2011-2022 走看看