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

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

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

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.加密解密代码;

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.读写文件

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.其他界面代码:

主界面代码:

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("注册成功~");}}
}

注册机代码:

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介绍),这样就不能反编译获得源码。

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

示例源码下载

C#软件license管理(简单软件注册机制)相关推荐

  1. C#实现软件授权,限定MAC运行(软件license管理,简单软件注册机制)

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

  2. deskvideosys软件license管理功能介绍及使用

    license管理功能是上网行为管理软件deskvideosys最近开发的一个功能,这个功能的主要作用就是管理软件的license信息,以及校验软件使用的截止日期,主要的功能包括license文件的查 ...

  3. 涉案财物管理软件:条形码管理简单规范

    安徽省某区检察院委托软件公司自主开发条形码管理系统软件,实现了涉案财物流转信息化管理.经过一年多的探索,该院依托统一业务应用系统和条形码涉案财物管理系统软件,形成了集信息登记.单据打印.流程管理.查询 ...

  4. c语言宿舍管理查询软件,宿舍管理查询软件--数据结构,c语言

    四.功能模块说明 输入学生宿舍信息模块:完成宿舍信息的录入,可以选择从平台手动输入,也可以选择从指定文件中读取. 保存学生宿舍信息模块,完成宿舍信息的保存. 排序学生宿舍信息模块,完成按关键字排序的功 ...

  5. 创业期的软件开发管理(二)

    接上文创业期的软件开发管理(一) 软件队伍 技术主管 决策者对软件开发可能一知半解,他们会想当然地认为软件开发过程比较"简单":从市场上找一个技术带头人,然后组建一个开发队伍,其余 ...

  6. LMT LicManager系统对license管理创新中的新附加值

     LMT LicManager系统对license管理创新中的新附加值 在当下,对软件license授权技术是软件作者通过自己采用的某种技术手段来实现软件的按授权license使用,license内容 ...

  7. 软件加密技术和注册机制加密基础(转)

    软件加密技术和注册机制加密基础 本文是一篇软件加密技术的基础性文章,简要介绍了软件加密的一些基本常识和一些加密产品,适用于国内软件开发商或者个人共享软件开发者阅读参考. 1.加密技术概述 一个密码系统 ...

  8. Flexlm介绍—常见EDA软件的license管理

    大型工程软件如Ansys.Fluent.Unigraph.ProE等安装需要经过注册程序Flexlm才可以使用,而Flexlm中涉及到很多知识.技巧,也存在许多问题.本篇文章就是针对上述软件安装中的常 ...

  9. 学会软件破解,让注册机制形同虚设

    一.    修改注册表文件,清除软件使用次数限制. 打开软件,首先跳出来一个注册的框,其中用户名可以随便填写.左下角红色的字显示还可以试用的次数.点击试用以后,可以进入软件.但是试用总共有100次.我 ...

最新文章

  1. EXT3与EXT4的主要区别
  2. protoc文件生成cs文件
  3. Hdu 1029 Ignatius and the Princess IV
  4. Shell(13)——find
  5. Oracle的resouce、unlimited tablespace 及如何把数据导入不同的表空间
  6. 使用ffmpeg进行h.264编码
  7. python迭代对象有哪些_Python可迭代对象操作示例
  8. Ubuntu中rsync配合inotify做服务器间文件同步
  9. ---perl 模块安装方法
  10. Ubuntu 16.04静态IP设置
  11. html 京东购物车样式,购物车css样式效果
  12. PyCharm安装教程
  13. android simplelistitem1,6.3.1 在列表中显示简单数据(2)
  14. selenium和requests实现12306登录及余票查询
  15. Linux中的虚拟机图形界面安装步骤,批量完成虚拟机硬件配置
  16. 巴别时代php面试题,巴别时代遇到的函数
  17. 国内有什么好的前端学习网站推荐?
  18. EM算法原理和python简单实现
  19. 数据权限设计:从RBAC到ABAC的演变
  20. 【DIY小记】解决CSGO打开游戏即闪退的问题

热门文章

  1. 2022-2027年中国激光雷达行业市场调研及未来发展趋势预测报告
  2. “伊凡 C普”第一式-内存管理
  3. python predictabel_统计学习方法的python实现
  4. [数论] 约数个数定理与约数和定理
  5. 上线MSF(Metasploit)的几种常见方式
  6. Java项目:Springboot汽车配件销售管理系统
  7. 计算机与网络五十四所有版面费吗,网络与信息化中心财务管理办法(暂行)
  8. linux 参考文献格式转化,科学网-Endnote向Bibtex格式的转换-郑小宏的博文
  9. 170 FPS!YolactEdge:边缘设备上的实时实例分割,已开源!
  10. 为什么人到了中年会喜欢上养花?养花能给人带来什么?