• 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
    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 < 6; 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 < pToDecrypt.Length / 2; 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();  
            }  
        }  
        /// <summary>  
        /// 试运行窗口  
        /// </summary>  
        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 < timeCount && isRegist == false)  
            {  
                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介绍),这样就不能反编译获得源码。
            至此全部完成,只是个人的一些实践,对自己是一个记录,同时希望也能对别人有些帮助,如果有什么错误,还望不吝指出,共同进步,转载请保留原文地址。
    ---------------------
    作者:weixin_37691493
    来源:CSDN
    原文:https://blog.csdn.net/weixin_37691493/article/details/79716050
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    【九】纯配置版本的微服务
    Eclipse 项目导航字体设置 左侧树字体
    【八】Spring Cloud Config
    Lua Table 操作
    根据角度和距离生成游戏物体(以圆心向圆圈线上生成物体)
    Unity UI和引用的管理中心
    利用三角函数实现按钮上下漂浮
    DoTween学习笔记(二) UGUI结合使用(实现一些简单效果)
    DoTween学习笔记(一)
    人物角色群体攻击判定四(三角区域判断)
  • 原文地址:https://www.cnblogs.com/xihong2014/p/13693747.html
Copyright © 2020-2023  润新知