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

C#实现软件授权,限定MAC运行(软件license管理,简单软件注册机制)的更多相关文章

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

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

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

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

  3. 适用于Mac 的自动补丁管理软件

    适用于Mac 的自动补丁管理软件 ManageEngine Desktop Central 的功能越来越神奇.系统管理员现在可以使用 Desktop Central 管理异构网络.即使是最复杂的任务, ...

  4. 如何在Mac上安全彻底的卸载软件?

    文章来源:知乎 收录于:风云社区(SCOEE)[提供mac软件下载] 更多专题,可关注小编[磨人的小妖精],查看我的文章,也可上[风云社区 SCOEE],查找和下载相关软件资源. (一)综合类: 新买 ...

  5. apple mac 下使用机械键盘的办法,键盘映射工具软件,apple mac Mechanical keyboard

    apple mac 下使用机械键盘的办法,键盘映射工具软件,apple mac Mechanical keyboard 想在苹果电脑 mac 系统下使用 机械键盘,大部分机械键盘不是为mac设计的,所 ...

  6. 软件授权协议有什么作用,例如GPL、Apache License、CDDL、EPL这些协议有什么区别?

    1.授权协议有什么作用:授权协议就是授予你使用或修改软件等权利,由于软件受到著作权保护,未经授权使用即是侵犯著作权,属于违法行为,所以同意或签署软件授权协议是你使用或修改软件的前提条件.既然是授权协议 ...

  7. NSIS:静默释放文件并运行 制作绿色单文件软件

    原文 NSIS:静默释放文件并运行 制作绿色单文件软件 现在所谓的绿色单文件软件,大多与以下代码原理相似:把软件运行需要的文件封装为一个EXE文件,双击时释放到某个目录(大多是TEMP)并运行主程序文 ...

  8. Mac 设计师必备的设计绘图软件 推荐与下载

    Mac设计师必备的设计绘图软件,为广大设计师推荐一些Mac上实用且强大的软件,使用好的软件,事半功倍,设计出精美的作品. Mac上优秀的设计类软件非常多,绝对不止这几款软件,看看以下内容,希望对你有帮 ...

  9. MAC上有哪些优秀的日常软件| 入门级Mac OS 用户必备软件

    本文整理的网友反馈的MAC上有哪些优秀的日常软件+入门级Mac OS 用户必备软件,感兴趣的朋友可以看看,下载下来试用一样便知实不实用.如有更好的推荐,欢迎留言. MAC上有哪些优秀的日常软件 Tim ...

随机推荐

  1. Sbulime Text 2 修改选中字符串的颜色

    Sublime Text 2 > Preferences > Browse Packages... 假设当前试用的 Color Scheme 是 Monokai,则在 Color Sche ...

  2. ESP8266 wifi干扰、钓鱼实现

    说明:绝大部分都是对着下面的参考文章来做的.这里只把基本流程和我自己遇到的问题写一下.如有其他问题可以访问文章末的参考文章进行查找! esp8266模块 我们需要购买一块esp8266模块,如下图所示 ...

  3. 将一个List拆分为n份的方法

    public static void main(String[] args) { List<Integer> taskList = new ArrayList<>(); for ...

  4. day 64 crm项目(1) admin组件的初识别以及应用

    前情提要: 今天进入项目学习阶段,crm 一个又老又土又实用的入门项目 一:django回顾 二:事前准备 1:首先创建django项目 2:在model中创建数据 from django.db im ...

  5. day 54 linux 常用指令入门

    Linux文件系统结构 Linux目录结构的组织形式和Windows有很大的不同.首先Linux没有“盘(C盘.D盘.E盘)”的概念.已经建立文件系统的硬盘分区被挂载到某一个目录下,用户通过操作目录来 ...

  6. jdbc连接1(可以注入)

    package demo3class; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepa ...

  7. celery初始化

    # 在任务处理者一端加初始化 import os import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", &qu ...

  8. 常见手机的useragent

    设备 系统 浏览器 User-Agent 华为Mate 10 Pro Android QQ浏览器 Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL ...

  9. appt查看应用包报名和入口页面

    appt在哪里? aapt不需要另外安装喔,有安装了adt的,可以直接在adt../sdk/build-tools/android-xx/下,找到aapt,详细路径如图 怎么使用aapt.bat? 直 ...

  10. iOS设置圆角的三种方式

    第一种方法:通过设置layer的属性 最简单的一种,但是很影响性能,一般在正常的开发中使用很少. ? 1 2 3 4 5 6 7 UIImageView *imageView = [[UIImageV ...