最近做了一个绿色免安装软件,领导临时要求加个注册机制,不能让现场工程师随意复制。事出突然,只能在现场开发(离开现场软件就不受我们控了)。花了不到两个小时实现了简单的注册机制,稍作整理。
        基本原理: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. Java中字符串以小数点分割时无效,String s = “12.34“; String[] ss = split(“.“);分割结果为空
  2. 优酷播控实践:基于规则引擎的投放管控模型
  3. Python数据可视化——matplotlib使用
  4. Ueditor的配置及使用
  5. Spring源码学习路线
  6. 美国一公司起诉苹果 指控iPhone中“个人热点”技术侵犯其专利
  7. PHP连接不上MySQL解决方案总结
  8. 硬币等于骰子(在统计学意义上)
  9. 【BZOJ】1270 [BeijingWc2008]雷涛的小猫
  10. 在 Mac OS X 安装gcc编辑环境,make不能用时参考
  11. C语言main函数的参数及其返回值详细解析
  12. html更改提示框内容,JS修改内容提示框字体样式
  13. bootmgr is missing错误:首先检查系统分区是否为活动分区
  14. Gartner:2017年存储技术成熟度曲线
  15. 龚本灿c语言程序设计,c语言程序设计初步-求索学堂.ppt
  16. 三位整数拆分python_343整数拆分
  17. 【js】Ajax提交form表单(ajaxSubmit使用讲解 )
  18. 服务器系统内存坏了会怎样,存储服务器故障的六大原因你知道几点?
  19. zabbix===》监控基础架构、邮箱报警、第三方平台电话报警
  20. 上海大学生计算机应用能力大赛答辩,2018年(第十届)上海市大学生计算机应用能力大赛成功举行...

热门文章

  1. 【实验四 循环结构】7-3 sdut- C语言实验-计算1到n的和(循环结构)
  2. linux so_linger,linux系统编程之getsockopt/setsockopt 函数
  3. ReadEveryDay From LuoJiLab
  4. ASP.NET计算机类专业毕业设计(课程设计)题目大全
  5. Sentinel 为 RocketMQ 服务保驾护航
  6. 什么是高端的IPv6?和IPv4有什么差别呢?
  7. VS2017 Git failed with a fatal error. Git failed with a fatal error. Need to specify how to reconcil
  8. 列车实时数据通信协议(TRDP)探索之路【三】
  9. QVD-2023-1953禅道系统 权限绕过 POC 伪静态传参版
  10. 如何在 JavaScript 中检查数字是正数还是负数