zoukankan      html  css  js  c++  java
  • C#软件license管理(简单软件注册机制)

    最近做了一个绿色免安装软件,领导临时要求加个注册机制,不能让现场工程师随意复制。事出突然,只能在现场开发(离开现场软件就不受我们控了)。花了不到两个小时实现了简单的注册机制,稍作整理。
            基本原理:1.软件一运行就把计算机的CPU、主板、BIOS、MAC地址记录下来,然后加密(key=key1)生成文件;2.注册机将该文件内容MD5加密后再进行一次加密(key=key2)保存成注册文件;3.注册验证的逻辑,计算机信息加密后(key=key1)加密md5==注册文件解密(key=key2);
    另外,采用ConfuserEx将可执行文件加密;这样别人要破解也就需要点力气了(没打算防破解,本意只想防复制的),有能力破解的人也不在乎破解这个软件了(开发这个软件前后只花了一周时间而已);

            技术上主要三个模块:1.获取电脑相关硬件信息(可参考);2.加密解密;3.读写文件;

            1.获取电脑相关硬件信息代码:

    [csharp] view plain copy
     
    1. public class ComputerInfo  
    2. {  
    3.     public static string GetComputerInfo()  
    4.     {  
    5.         string info = string.Empty;  
    6.         string cpu = GetCPUInfo();  
    7.         string baseBoard = GetBaseBoardInfo();  
    8.         string bios = GetBIOSInfo();  
    9.         string mac = GetMACInfo();  
    10.         info = string.Concat(cpu, baseBoard, bios, mac);  
    11.         return info;  
    12.     }  
    13.   
    14.     private static string GetCPUInfo()  
    15.     {  
    16.         string info = string.Empty;  
    17.         info = GetHardWareInfo("Win32_Processor", "ProcessorId");  
    18.         return info;  
    19.     }  
    20.     private static string GetBIOSInfo()  
    21.     {  
    22.         string info = string.Empty;  
    23.         info = GetHardWareInfo("Win32_BIOS", "SerialNumber");  
    24.         return info;  
    25.     }  
    26.     private static string GetBaseBoardInfo()  
    27.     {  
    28.         string info = string.Empty;  
    29.         info = GetHardWareInfo("Win32_BaseBoard", "SerialNumber");  
    30.         return info;  
    31.     }  
    32.     private static string GetMACInfo()  
    33.     {  
    34.         string info = string.Empty;  
    35.         info = GetHardWareInfo("Win32_BaseBoard", "SerialNumber");  
    36.         return info;  
    37.     }  
    38.     private static string GetHardWareInfo(string typePath, string key)  
    39.     {  
    40.         try  
    41.         {  
    42.             ManagementClass managementClass = new ManagementClass(typePath);  
    43.             ManagementObjectCollection mn = managementClass.GetInstances();  
    44.             PropertyDataCollection properties = managementClass.Properties;  
    45.             foreach (PropertyData property in properties)  
    46.             {  
    47.                 if (property.Name == key)  
    48.                 {  
    49.                     foreach (ManagementObject m in mn)  
    50.                     {  
    51.                         return m.Properties[property.Name].Value.ToString();  
    52.                     }  
    53.                 }  
    54.   
    55.             }  
    56.         }  
    57.         catch (Exception ex)  
    58.         {  
    59.             //这里写异常的处理    
    60.         }  
    61.         return string.Empty;  
    62.     }  
    63.     private static string GetMacAddressByNetworkInformation()  
    64.     {  
    65.         string key = "SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\";  
    66.         string macAddress = string.Empty;  
    67.         try  
    68.         {  
    69.             NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();  
    70.             foreach (NetworkInterface adapter in nics)  
    71.             {  
    72.                 if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet  
    73.                     && adapter.GetPhysicalAddress().ToString().Length != 0)  
    74.                 {  
    75.                     string fRegistryKey = key + adapter.Id + "\Connection";  
    76.                     RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false);  
    77.                     if (rk != null)  
    78.                     {  
    79.                         string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString();  
    80.                         int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0));  
    81.                         if (fPnpInstanceID.Length > 3 &&  
    82.                             fPnpInstanceID.Substring(0, 3) == "PCI")  
    83.                         {  
    84.                             macAddress = adapter.GetPhysicalAddress().ToString();  
    85.                             for (int i = 1; i < 6; i++)  
    86.                             {  
    87.                                 macAddress = macAddress.Insert(3 * i - 1, ":");  
    88.                             }  
    89.                             break;  
    90.                         }  
    91.                     }  
    92.   
    93.                 }  
    94.             }  
    95.         }  
    96.         catch (Exception ex)  
    97.         {  
    98.             //这里写异常的处理    
    99.         }  
    100.         return macAddress;  
    101.     }  
    102. }  

            2.加密解密代码;

    [csharp] view plain copy
     
    1. public enum EncryptionKeyEnum  
    2. {  
    3.     KeyA,  
    4.     KeyB  
    5. }  
    6. public class EncryptionHelper  
    7. {  
    8.     string encryptionKeyA = "pfe_Nova";  
    9.     string encryptionKeyB = "WorkHard";  
    10.     string md5Begin = "Hello";  
    11.     string md5End = "World";  
    12.     string encryptionKey = string.Empty;  
    13.     public EncryptionHelper()  
    14.     {  
    15.         this.InitKey();  
    16.     }  
    17.     public EncryptionHelper(EncryptionKeyEnum key)  
    18.     {  
    19.         this.InitKey(key);  
    20.     }  
    21.     private void InitKey(EncryptionKeyEnum key = EncryptionKeyEnum.KeyA)  
    22.     {  
    23.         switch (key)  
    24.         {  
    25.             case EncryptionKeyEnum.KeyA:  
    26.                 encryptionKey = encryptionKeyA;  
    27.                 break;  
    28.             case EncryptionKeyEnum.KeyB:  
    29.                 encryptionKey = encryptionKeyB;  
    30.                 break;  
    31.         }  
    32.     }  
    33.   
    34.     public string EncryptString(string str)  
    35.     {  
    36.         return Encrypt(str, encryptionKey);  
    37.     }  
    38.     public string DecryptString(string str)  
    39.     {  
    40.         return Decrypt(str, encryptionKey);  
    41.     }  
    42.     public string GetMD5String(string str)  
    43.     {  
    44.         str = string.Concat(md5Begin, str, md5End);  
    45.         MD5 md5 = new MD5CryptoServiceProvider();  
    46.         byte[] fromData = Encoding.Unicode.GetBytes(str);  
    47.         byte[] targetData = md5.ComputeHash(fromData);  
    48.         string md5String = string.Empty;  
    49.         foreach (var b in targetData)  
    50.             md5String += b.ToString("x2");  
    51.         return md5String;  
    52.     }  
    53.   
    54.     private string Encrypt(string str, string sKey)  
    55.     {  
    56.         DESCryptoServiceProvider des = new DESCryptoServiceProvider();  
    57.         byte[] inputByteArray = Encoding.Default.GetBytes(str);  
    58.         des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  
    59.         des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  
    60.         MemoryStream ms = new MemoryStream();  
    61.         CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);  
    62.         cs.Write(inputByteArray, 0, inputByteArray.Length);  
    63.         cs.FlushFinalBlock();  
    64.         StringBuilder ret = new StringBuilder();  
    65.         foreach (byte b in ms.ToArray())  
    66.         {  
    67.             ret.AppendFormat("{0:X2}", b);  
    68.         }  
    69.         ret.ToString();  
    70.         return ret.ToString();  
    71.     }  
    72.     private string Decrypt(string pToDecrypt, string sKey)  
    73.     {  
    74.         DESCryptoServiceProvider des = new DESCryptoServiceProvider();  
    75.         byte[] inputByteArray = new byte[pToDecrypt.Length / 2];  
    76.         for (int x = 0; x < pToDecrypt.Length / 2; x++)  
    77.         {  
    78.             int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));  
    79.             inputByteArray[x] = (byte)i;  
    80.         }  
    81.         des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  
    82.         des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  
    83.         MemoryStream ms = new MemoryStream();  
    84.         CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);  
    85.         cs.Write(inputByteArray, 0, inputByteArray.Length);  
    86.         cs.FlushFinalBlock();  
    87.         StringBuilder ret = new StringBuilder();  
    88.         return System.Text.Encoding.Default.GetString(ms.ToArray());  
    89.     }  
    90. }  

            注:这边在MD5时前后各加了一段字符,这样增加一点破解难度。

            3.读写文件

    [csharp] view plain copy
     
    1. public class RegistFileHelper  
    2. {  
    3.     public static string ComputerInfofile = "ComputerInfo.key";  
    4.     public static string RegistInfofile = "RegistInfo.key";  
    5.     public static void WriteRegistFile(string info)  
    6.     {  
    7.         WriteFile(info, RegistInfofile);  
    8.     }  
    9.     public static void WriteComputerInfoFile(string info)  
    10.     {  
    11.         WriteFile(info, ComputerInfofile);  
    12.     }  
    13.     public static string ReadRegistFile()  
    14.     {  
    15.         return ReadFile(RegistInfofile);  
    16.     }  
    17.     public static string ReadComputerInfoFile()  
    18.     {  
    19.         return ReadFile(ComputerInfofile);  
    20.     }  
    21.     public static bool ExistComputerInfofile()  
    22.     {  
    23.         return File.Exists(ComputerInfofile);  
    24.     }  
    25.     public static bool ExistRegistInfofile()  
    26.     {  
    27.         return File.Exists(RegistInfofile);  
    28.     }  
    29.     private static void WriteFile(string info, string fileName)  
    30.     {  
    31.         try  
    32.         {  
    33.             using (StreamWriter sw = new StreamWriter(fileName, false))  
    34.             {  
    35.                 sw.Write(info);  
    36.                 sw.Close();  
    37.             }  
    38.         }  
    39.         catch (Exception ex)  
    40.         {  
    41.         }  
    42.     }  
    43.     private static string ReadFile(string fileName)  
    44.     {  
    45.         string info = string.Empty;  
    46.         try  
    47.         {  
    48.             using (StreamReader sr = new StreamReader(fileName))  
    49.             {  
    50.                 info = sr.ReadToEnd();  
    51.                 sr.Close();  
    52.             }  
    53.         }  
    54.         catch (Exception ex)  
    55.         {  
    56.         }  
    57.         return info;  
    58.     }  
    59. }  

            4.其他界面代码:

            主界面代码:

    [csharp] view plain copy
     
    1. public partial class FormMain : Form  
    2. {  
    3.     private string encryptComputer = string.Empty;  
    4.     private bool isRegist = false;  
    5.     private const int timeCount = 30;  
    6.     public FormMain()  
    7.     {  
    8.         InitializeComponent();  
    9.         Control.CheckForIllegalCrossThreadCalls = false;  
    10.     }  
    11.     private void FormMain_Load(object sender, EventArgs e)  
    12.     {  
    13.         string computer = ComputerInfo.GetComputerInfo();  
    14.         encryptComputer = new EncryptionHelper().EncryptString(computer);  
    15.         if (CheckRegist() == true)  
    16.         {  
    17.             lbRegistInfo.Text = "已注册";  
    18.         }  
    19.         else  
    20.         {  
    21.             lbRegistInfo.Text = "待注册,运行十分钟后自动关闭";  
    22.             RegistFileHelper.WriteComputerInfoFile(encryptComputer);  
    23.             TryRunForm();  
    24.         }  
    25.     }  
    26.     /// <summary>  
    27.     /// 试运行窗口  
    28.     /// </summary>  
    29.     private void TryRunForm()  
    30.     {  
    31.         Thread threadClose = new Thread(CloseForm);  
    32.         threadClose.IsBackground = true;  
    33.         threadClose.Start();  
    34.     }  
    35.     private bool CheckRegist()  
    36.     {  
    37.         EncryptionHelper helper = new EncryptionHelper();  
    38.         string md5key = helper.GetMD5String(encryptComputer);  
    39.         return CheckRegistData(md5key);  
    40.     }  
    41.     private bool CheckRegistData(string key)  
    42.     {  
    43.         if (RegistFileHelper.ExistRegistInfofile() == false)  
    44.         {  
    45.             isRegist = false;  
    46.             return false;  
    47.         }  
    48.         else  
    49.         {  
    50.             string info = RegistFileHelper.ReadRegistFile();  
    51.             var helper = new EncryptionHelper(EncryptionKeyEnum.KeyB);  
    52.             string registData = helper.DecryptString(info);  
    53.             if (key == registData)  
    54.             {  
    55.                 isRegist = true;  
    56.                 return true;  
    57.             }  
    58.             else  
    59.             {  
    60.                 isRegist = false;  
    61.                 return false;  
    62.             }  
    63.         }  
    64.     }  
    65.     private void CloseForm()  
    66.     {  
    67.         int count = 0;  
    68.         while (count < timeCount && isRegist == false)  
    69.         {  
    70.             if (isRegist == true)  
    71.             {  
    72.                 return;  
    73.             }  
    74.             Thread.Sleep(1 * 1000);  
    75.             count++;  
    76.         }  
    77.         if (isRegist == true)  
    78.         {  
    79.             return;  
    80.         }  
    81.         else  
    82.         {  
    83.             this.Close();  
    84.         }  
    85.     }  
    86.   
    87.     private void btnRegist_Click(object sender, EventArgs e)  
    88.     {  
    89.         if (lbRegistInfo.Text == "已注册")  
    90.         {  
    91.             MessageBox.Show("已经注册~");  
    92.             return;  
    93.         }  
    94.         string fileName = string.Empty;  
    95.         OpenFileDialog openFileDialog = new OpenFileDialog();  
    96.         if (openFileDialog.ShowDialog() == DialogResult.OK)  
    97.         {  
    98.             fileName = openFileDialog.FileName;  
    99.         }  
    100.         else  
    101.         {  
    102.             return;  
    103.         }  
    104.         string localFileName = string.Concat(  
    105.             Environment.CurrentDirectory,  
    106.             Path.DirectorySeparatorChar,  
    107.             RegistFileHelper.RegistInfofile);  
    108.         if (fileName != localFileName)  
    109.             File.Copy(fileName, localFileName, true);  
    110.   
    111.         if (CheckRegist() == true)  
    112.         {  
    113.             lbRegistInfo.Text = "已注册";  
    114.             MessageBox.Show("注册成功~");  
    115.         }  
    116.     }  
    117. }  

            注册机代码:

    [csharp] view plain copy
     
    1. public partial class FormMain : Form  
    2. {  
    3.     public FormMain()  
    4.     {  
    5.         InitializeComponent();  
    6.     }  
    7.   
    8.     private void btnRegist_Click(object sender, EventArgs e)  
    9.     {  
    10.         string fileName = string.Empty;  
    11.         OpenFileDialog openFileDialog = new OpenFileDialog();  
    12.         if (openFileDialog.ShowDialog() == DialogResult.OK)  
    13.         {  
    14.             fileName = openFileDialog.FileName;  
    15.         }  
    16.         else  
    17.         {  
    18.             return;  
    19.         }  
    20.         string localFileName = string.Concat(  
    21.             Environment.CurrentDirectory,  
    22.             Path.DirectorySeparatorChar,  
    23.             RegistFileHelper.ComputerInfofile);  
    24.   
    25.         if (fileName != localFileName)  
    26.             File.Copy(fileName, localFileName, true);  
    27.         string computer = RegistFileHelper.ReadComputerInfoFile();  
    28.         EncryptionHelper help = new EncryptionHelper(EncryptionKeyEnum.KeyB);  
    29.         string md5String = help.GetMD5String(computer);  
    30.         string registInfo = help.EncryptString(md5String);  
    31.         RegistFileHelper.WriteRegistFile(registInfo);  
    32.         MessageBox.Show("注册码已生成");  
    33.     }  
    34. }  

            最后采用ConfuserEx将可执行文件加密(ConfuserEx介绍),这样就不能反编译获得源码。

            至此全部完成,只是个人的一些实践,对自己是一个记录,同时希望也能对别人有些帮助,如果有什么错误,还望不吝指出,共同进步,转载请保留原文地址

            示例源码下载

  • 相关阅读:
    【判环】Perpetuum Mobile
    【计算几何】Water Testing
    【动态规划】Überwatch
    【规律】Cunning Friends
    【转载】【最短路Floyd+KM 最佳匹配】hdu 2448 Mining Station on the Sea
    【动态规划】Concerts
    【计算几何】The Queen’s Super-circular Patio
    【规律】Farey Sums
    【规律】Growing Rectangular Spiral
    Mancala II
  • 原文地址:https://www.cnblogs.com/soundcode/p/6533423.html
Copyright © 2011-2022 走看看