一个绿色免安装软件,领导临时要求加个注册机制,不能让现场工程师随意复制。事出突然,只能在现场开发(离开现场软件就不受我们控了)。花了不到两个小时实现了简单的注册机制,稍作整理。 
基本原理: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介绍),这样就不能反编译获得源码。

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

https://download.csdn.net/download/pfe_nova/7943235

https://www.cnblogs.com/hanzhaoxin/archive/2013/01/04/2844191.html

转载于:https://www.cnblogs.com/xiaohua19920/p/9821531.html

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

  1. clementine for Mac(多平台音乐管理播放软件)

    clementine音乐管理器可以轻松控制音乐聆听的各个方面,管理播放列表,使用Spotify,SKY.fm,Grooveshark,Last.fm等网络流广播,将音乐传输到您的便携式设备(支持App ...

  2. 软件授权加密算法研究

    软件授权加密算法研究 转载自 brucevanfdm . 介绍 软件授权机制的基础就是加密算法.加密算法可以简单分为对称加密算法(加解密均采用同一密钥)和非对称加密算法(采用公钥加密,私钥解密或私钥签 ...

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

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

  4. 从软件保护到软件授权

    软件保护的概念是站在开发商的角度出发的,它强调的是软件加密和不被盗版.常用的软件保护方式有软件加密和硬件加密两种.软件授权的概念则是同时考虑了开发商和最终用户两方面的感受而提出的."授权&q ...

  5. mac运行ps特别慢_Mac Mac运行越来越慢?变卡顿?试试看这些加快小诀窍!

    使用 Mac 一阵子之后,有可能有电脑越变越慢的感觉,当初购买电脑时那飞快的感觉已经不在:如果你用的是旧款 Mac,这种感觉可能更加深刻.速度变慢除了电脑本身慢慢老旧外,也很可能是软件越装越多,开始拖 ...

  6. C#软件license管理(简单软件注册机制)

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

  7. Mac 运行windows软件

    常见的通过自带的Boot Camp助理安装windows系统,或者使用虚拟机,相关教程网上较多就不放了,下面介绍一个软件CrossOver 网站链接点击打开链接 兼容 Sierra 的 CrossOv ...

  8. Tunnelblick mac是一款在主机操作系统上运行VP~解决方案的跳板软件。

    Tunnelblick mac是一款在主机操作系统上运行VP~解决方案的跳板软件,Tunnelblick Mac版是一款非常实用的网络工具,该软件绿色小巧.功能强大,它设置了一个控制器项目菜单栏,让您 ...

  9. mac软件更新卡住不动_如何修复Mac运行缓慢?修复它的五种简单方法

    在使用Mac几年之后,您可能会发现Macbook或iMac的启动时间更长,或者经常遇到烦人的沙滩球.是的,您的Mac正在缓慢运行.为了获得更好的性能,无论您是玩游戏还是使用某些可运行的应用程序,某些用 ...

最新文章

  1. php文章排序,PHP+Ajax实现后台文章快速排序
  2. 实现Excel数据导入到SQL2005中的方法(回顾)
  3. ps4修改服务器地区,ps4怎么修改服务器地址
  4. java基础之XML
  5. JUnit-4.12使用报java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing错误
  6. 使用TASM时报错extra characters on line的解决办法
  7. SunnyOS准备4
  8. java batik_batik详解1
  9. 微服务 注册中心的作用_微服务-服务与注册中心
  10. matlab中mcc失败,matlab运行mcc时出现这样的情况
  11. Block-scoped declarations (let, const, function, class) not yet supported outs报错解决
  12. 毕业设计-基于SpringBoot幼儿园管理系统
  13. 再谈 共轭方向法/Conjugate Direction Method In Optimization
  14. 程序员的工资被严重高估?
  15. 电视端虚拟鼠标的设计
  16. 分享一个自媒体副业,认真做可以月入6000+
  17. window.print()打印网页局部内容
  18. 国信蓝点杯C语言高职高专组考试题目--记不太清了,大致就这些题目
  19. 补贴大战,烧不出社区团购的未来
  20. 计算机网络会议排名,计算机通信网络领域的顶级期刊会议排名,和投稿心得分享...

热门文章

  1. HTTP 和 WebSocket的区别
  2. ubuntu下解决wireshark权限问题
  3. ANDROID窗体跳转
  4. 361766103.jpg
  5. nyromodal 非常棒的弹出层,可内嵌各种文件
  6. 口译分类词汇:上海景点名集锦
  7. Mobile-LPR——面向移动端的准商业级车牌识别库
  8. StegaStamp:加州大学伯克利分校开源神奇的照片隐写术,打印的照片能当二维码用...
  9. mysql 实现非递归树_二叉树的非递归前序,中序,后序遍历算法
  10. mysql容器重启数据是否丢失_docker容器重启 数据会丢吗