您现在的位置是: 首页 >  .NET开发 >  文章详情 文章详情

C#软件授权、注册、加密、解密模块源码解析并制作注册机生成license

2019-08-19 【.NET开发】 1605人浏览

最近做了一个绿色免安装软件,领导临时要求加个注册机制,不能让现场工程师随意复制。事出突然,只能在现场开发(离开现场软件就不受我们控了)。花了不到两个小时实现了简单的注册机制,稍作整理。

        基本原理: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

public class ComputerInfo  

{  

    public static string GetComputerInfo()  

    {  

        string info = string.Empty;  

        string cpu = GetCPUInfo();  

        string baseBoard = GetBaseBoardInfo();  

        string bios = GetBIOSInfo();  

        string mac = GetMACInfo();  

        info = string.Concat(cpu, baseBoard, bios, mac);  

        return info;  

    }  

  

    private static string GetCPUInfo()  

    {  

        string info = string.Empty;  

        info = GetHardWareInfo("Win32_Processor", "ProcessorId");  

        return info;  

    }  

    private static string GetBIOSInfo()  

    {  

        string info = string.Empty;  

        info = GetHardWareInfo("Win32_BIOS", "SerialNumber");  

        return info;  

    }  

    private static string GetBaseBoardInfo()  

    {  

        string info = string.Empty;  

        info = GetHardWareInfo("Win32_BaseBoard", "SerialNumber");  

        return info;  

    }  

    private static string GetMACInfo()  

    {  

        string info = string.Empty;  

        info = GetHardWareInfo("Win32_BaseBoard", "SerialNumber");  

        return info;  

    }  

    private static string GetHardWareInfo(string typePath, string key)  

    {  

        try  

        {  

            ManagementClass managementClass = new ManagementClass(typePath);  

            ManagementObjectCollection mn = managementClass.GetInstances();  

            PropertyDataCollection properties = managementClass.Properties;  

            foreach (PropertyData property in properties)  

            {  

                if (property.Name == key)  

                {  

                    foreach (ManagementObject m in mn)  

                    {  

                        return m.Properties[property.Name].Value.ToString();  

                    }  

                }  

  

            }  

        }  

        catch (Exception ex)  

        {  

            //这里写异常的处理    

        }  

        return string.Empty;  

    }  

    private static string GetMacAddressByNetworkInformation()  

    {  

        string key = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";  

        string macAddress = string.Empty;  

        try  

        {  

            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();  

            foreach (NetworkInterface adapter in nics)  

            {  

                if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet  

                    && adapter.GetPhysicalAddress().ToString().Length != 0)  

                {  

                    string fRegistryKey = key + adapter.Id + "\\Connection";  

                    RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false);  

                    if (rk != null)  

                    {  

                        string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString();  

                        int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0));  

                        if (fPnpInstanceID.Length > 3 &&  

                            fPnpInstanceID.Substring(0, 3) == "PCI")  

                        {  

                            macAddress = adapter.GetPhysicalAddress().ToString();  

                            for (int i = 1; i

                            {  

                                macAddress = macAddress.Insert(3 * i - 1, ":");  

                            }  

                            break;  

                        }  

                    }  

  

                }  

            }  

        }  

        catch (Exception ex)  

        {  

            //这里写异常的处理    

        }  

        return macAddress;  

    }  

}  

        2.加密解密代码;

[csharp] view plain copy

public enum EncryptionKeyEnum  

{  

    KeyA,  

    KeyB  

}  

public class EncryptionHelper  

{  

    string encryptionKeyA = "pfe_Nova";  

    string encryptionKeyB = "WorkHard";  

    string md5Begin = "Hello";  

    string md5End = "World";  

    string encryptionKey = string.Empty;  

    public EncryptionHelper()  

    {  

        this.InitKey();  

    }  

    public EncryptionHelper(EncryptionKeyEnum key)  

    {  

        this.InitKey(key);  

    }  

    private void InitKey(EncryptionKeyEnum key = EncryptionKeyEnum.KeyA)  

    {  

        switch (key)  

        {  

            case EncryptionKeyEnum.KeyA:  

                encryptionKey = encryptionKeyA;  

                break;  

            case EncryptionKeyEnum.KeyB:  

                encryptionKey = encryptionKeyB;  

                break;  

        }  

    }  

  

    public string EncryptString(string str)  

    {  

        return Encrypt(str, encryptionKey);  

    }  

    public string DecryptString(string str)  

    {  

        return Decrypt(str, encryptionKey);  

    }  

    public string GetMD5String(string str)  

    {  

        str = string.Concat(md5Begin, str, md5End);  

        MD5 md5 = new MD5CryptoServiceProvider();  

        byte[] fromData = Encoding.Unicode.GetBytes(str);  

        byte[] targetData = md5.ComputeHash(fromData);  

        string md5String = string.Empty;  

        foreach (var b in targetData)  

            md5String += b.ToString("x2");  

        return md5String;  

    }  

  

    private string Encrypt(string str, string sKey)  

    {  

        DESCryptoServiceProvider des = new DESCryptoServiceProvider();  

        byte[] inputByteArray = Encoding.Default.GetBytes(str);  

        des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  

        des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  

        MemoryStream ms = new MemoryStream();  

        CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);  

        cs.Write(inputByteArray, 0, inputByteArray.Length);  

        cs.FlushFinalBlock();  

        StringBuilder ret = new StringBuilder();  

        foreach (byte b in ms.ToArray())  

        {  

            ret.AppendFormat("{0:X2}", b);  

        }  

        ret.ToString();  

        return ret.ToString();  

    }  

    private string Decrypt(string pToDecrypt, string sKey)  

    {  

        DESCryptoServiceProvider des = new DESCryptoServiceProvider();  

        byte[] inputByteArray = new byte[pToDecrypt.Length / 2];  

        for (int x = 0; x

        {  

            int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));  

            inputByteArray[x] = (byte)i;  

        }  

        des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  

        des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  

        MemoryStream ms = new MemoryStream();  

        CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);  

        cs.Write(inputByteArray, 0, inputByteArray.Length);  

        cs.FlushFinalBlock();  

        StringBuilder ret = new StringBuilder();  

        return System.Text.Encoding.Default.GetString(ms.ToArray());  

    }  

}  

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

        3.读写文件

[csharp] view plain copy

public class RegistFileHelper  

{  

    public static string ComputerInfofile = "ComputerInfo.key";  

    public static string RegistInfofile = "RegistInfo.key";  

    public static void WriteRegistFile(string info)  

    {  

        WriteFile(info, RegistInfofile);  

    }  

    public static void WriteComputerInfoFile(string info)  

    {  

        WriteFile(info, ComputerInfofile);  

    }  

    public static string ReadRegistFile()  

    {  

        return ReadFile(RegistInfofile);  

    }  

    public static string ReadComputerInfoFile()  

    {  

        return ReadFile(ComputerInfofile);  

    }  

    public static bool ExistComputerInfofile()  

    {  

        return File.Exists(ComputerInfofile);  

    }  

    public static bool ExistRegistInfofile()  

    {  

        return File.Exists(RegistInfofile);  

    }  

    private static void WriteFile(string info, string fileName)  

    {  

        try  

        {  

            using (StreamWriter sw = new StreamWriter(fileName, false))  

            {  

                sw.Write(info);  

                sw.Close();  

            }  

        }  

        catch (Exception ex)  

        {  

        }  

    }  

    private static string ReadFile(string fileName)  

    {  

        string info = string.Empty;  

        try  

        {  

            using (StreamReader sr = new StreamReader(fileName))  

            {  

                info = sr.ReadToEnd();  

                sr.Close();  

            }  

        }  

        catch (Exception ex)  

        {  

        }  

        return info;  

    }  

}  

        4.其他界面代码:

        主界面代码:

[csharp] view plain copy

public partial class FormMain : Form  

{  

    private string encryptComputer = string.Empty;  

    private bool isRegist = false;  

    private const int timeCount = 30;  

    public FormMain()  

    {  

        InitializeComponent();  

        Control.CheckForIllegalCrossThreadCalls = false;  

    }  

    private void FormMain_Load(object sender, EventArgs e)  

    {  

        string computer = ComputerInfo.GetComputerInfo();  

        encryptComputer = new EncryptionHelper().EncryptString(computer);  

        if (CheckRegist() == true)  

        {  

            lbRegistInfo.Text = "已注册";  

        }  

        else  

        {  

            lbRegistInfo.Text = "待注册,运行十分钟后自动关闭";  

            RegistFileHelper.WriteComputerInfoFile(encryptComputer);  

            TryRunForm();  

        }  

    }  

    ///

  

    /// 试运行窗口  

    ///   

    private void TryRunForm()  

    {  

        Thread threadClose = new Thread(CloseForm);  

        threadClose.IsBackground = true;  

        threadClose.Start();  

    }  

    private bool CheckRegist()  

    {  

        EncryptionHelper helper = new EncryptionHelper();  

        string md5key = helper.GetMD5String(encryptComputer);  

        return CheckRegistData(md5key);  

    }  

    private bool CheckRegistData(string key)  

    {  

        if (RegistFileHelper.ExistRegistInfofile() == false)  

        {  

            isRegist = false;  

            return false;  

        }  

        else  

        {  

            string info = RegistFileHelper.ReadRegistFile();  

            var helper = new EncryptionHelper(EncryptionKeyEnum.KeyB);  

            string registData = helper.DecryptString(info);  

            if (key == registData)  

            {  

                isRegist = true;  

                return true;  

            }  

            else  

            {  

                isRegist = false;  

                return false;  

            }  

        }  

    }  

    private void CloseForm()  

    {  

        int count = 0;  

        while (count

        {  

            if (isRegist == true)  

            {  

                return;  

            }  

            Thread.Sleep(1 * 1000);  

            count++;  

        }  

        if (isRegist == true)  

        {  

            return;  

        }  

        else  

        {  

            this.Close();  

        }  

    }  

  

    private void btnRegist_Click(object sender, EventArgs e)  

    {  

        if (lbRegistInfo.Text == "已注册")  

        {  

            MessageBox.Show("已经注册~");  

            return;  

        }  

        string fileName = string.Empty;  

        OpenFileDialog openFileDialog = new OpenFileDialog();  

        if (openFileDialog.ShowDialog() == DialogResult.OK)  

        {  

            fileName = openFileDialog.FileName;  

        }  

        else  

        {  

            return;  

        }  

        string localFileName = string.Concat(  

            Environment.CurrentDirectory,  

            Path.DirectorySeparatorChar,  

            RegistFileHelper.RegistInfofile);  

        if (fileName != localFileName)  

            File.Copy(fileName, localFileName, true);  

  

        if (CheckRegist() == true)  

        {  

            lbRegistInfo.Text = "已注册";  

            MessageBox.Show("注册成功~");  

        }  

    }  

}  

        注册机代码:

[csharp] view plain copy

public partial class FormMain : Form  

{  

    public FormMain()  

    {  

        InitializeComponent();  

    }  

  

    private void btnRegist_Click(object sender, EventArgs e)  

    {  

        string fileName = string.Empty;  

        OpenFileDialog openFileDialog = new OpenFileDialog();  

        if (openFileDialog.ShowDialog() == DialogResult.OK)  

        {  

            fileName = openFileDialog.FileName;  

        }  

        else  

        {  

            return;  

        }  

        string localFileName = string.Concat(  

            Environment.CurrentDirectory,  

            Path.DirectorySeparatorChar,  

            RegistFileHelper.ComputerInfofile);  

  

        if (fileName != localFileName)  

            File.Copy(fileName, localFileName, true);  

        string computer = RegistFileHelper.ReadComputerInfoFile();  

        EncryptionHelper help = new EncryptionHelper(EncryptionKeyEnum.KeyB);  

        string md5String = help.GetMD5String(computer);  

        string registInfo = help.EncryptString(md5String);  

        RegistFileHelper.WriteRegistFile(registInfo);  

        MessageBox.Show("注册码已生成");  

    }  

}  

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

 ———————————————— 

原文链接:https://blog.csdn.net/weixin_37691493/article/details/79716050



很赞哦! (0)

站长推荐