using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
namespace LicenseLib
{
///
/// C# 离线防破解 + 序列号授权核心类
/// 使用方式见 README.md
///
public static class LicenseHelper
{
// ⚠️ 请修改为你自己的私钥(越长越安全)
// 注意:这里展示的是异或加密后的存储方式,实际源码中看不到明文
private static readonly byte[] _privateKeyEncrypted = { 0x4D, 0x79, 0x53, 0x65, 0x63,
0x72, 0x65, 0x74, 0x32, 0x30, 0x32, 0x36, 0x30, 0x35, 0x31, 0x38 };
private const byte _xorKey = 0x2A;
///
/// 解密获取私钥(运行时才解密,反编译看不到明文)
///
private static string GetPrivateKey()
{
byte[] decrypted = new byte[_privateKeyEncrypted.Length];
for (int i = 0; i < _privateKeyEncrypted.Length; i++)
decrypted[i] = (byte)(_privateKeyEncrypted[i] ^ _xorKey);
string key = Encoding.UTF8.GetString(decrypted);
// 用完清内存
Array.Clear(decrypted, 0, decrypted.Length);
return key;
}
///
/// 获取硬盘序列号
///
private static string GetDiskSN()
{
try
{
using (ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk"))
{
foreach (ManagementObject disk in diskClass.GetInstances())
{
string sn = disk["VolumeSerialNumber"]?.ToString() ?? "";
if (!string.IsNullOrEmpty(sn))
return sn;
}
}
}
catch { /* 降级处理 */ }
return "DISK_UNKNOWN";
}
///
/// 获取 CPU 编号
///
private static string GetCpuID()
{
try
{
using (ManagementClass mc = new ManagementClass("Win32_Processor"))
{
foreach (ManagementObject mo in mc.GetInstances())
{
string id = mo["ProcessorId"]?.ToString() ?? "";
if (!string.IsNullOrEmpty(id))
return id;
}
}
}
catch { /* 降级处理 */ }
return "CPU_UNKNOWN";
}
///
/// 合成最终机器码(硬盘+CPU 组合 + MD5 压缩)
///
public static string GetLocalMachineCode()
{
string raw = GetDiskSN() + GetCpuID();
using (MD5 md5 = MD5.Create())
{
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(raw));
return BitConverter.ToString(hash).Replace("-", "").ToUpper();
}
}
///
/// 离线生成注册码(供开发者使用——你在自己电脑上跑这个)
///
/// 用户提供的机器码
/// 格式化的注册码 XXXX-XXXX-XXXX-XXXX
public static string CreateRegisterCode(string machineCode)
{
string privateKey = GetPrivateKey();
string raw = machineCode + privateKey;
// 用完清私钥内存
Array.Clear(privateKey.ToCharArray(), 0, privateKey.Length);
using (SHA256 sha256 = SHA256.Create())
{
byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(raw));
string fullCode = BitConverter.ToString(hash).Replace("-", "").ToUpper();
// 分割成 4 段序列号
return $"{fullCode.Substring(0, 4)}-{fullCode.Substring(4, 4)}-" +
$"{fullCode.Substring(8, 4)}-{fullCode.Substring(12, 4)}";
}
}
///
/// 程序内本地校验序列号
///
/// 用户输入的注册码
/// 本机机器码
/// 是否校验通过
public static bool CheckRegister(string inputCode, string localMachineCode)
{
if (string.IsNullOrWhiteSpace(inputCode) || string.IsNullOrWhiteSpace(localMachineCode))
return false;
// 移除常见分隔符,统一比较
string cleanedInput = inputCode.Replace("-", "").Replace(" ", "").Replace("_", "").ToUpper();
string rightCode = CreateRegisterCode(localMachineCode).Replace("-", "").ToUpper();
bool result = cleanedInput == rightCode;
// 故意加一点迷惑性的延时(增加爆破难度)
System.Threading.Thread.Sleep(50);
return result;
}
///
/// 保存已授权标志(加密存储到本地文件)
///
public static void SaveLicensedFlag()
{
try
{
string flagPath = Path.Combine(Application.StartupPath, ".license");
string machineCode = GetLocalMachineCode();
string raw = machineCode + GetPrivateKey() + "LICENSED";
using (SHA256 sha256 = SHA256.Create())
{
byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(raw));
string encoded = Convert.ToBase64String(hash);
File.WriteAllText(flagPath, encoded, Encoding.UTF8);
}
}
catch { /* 静默失败,不影响主流程 */ }
}
///
/// 检查是否已授权
///
public static bool IsLicensed()
{
try
{
string flagPath = Path.Combine(Application.StartupPath, ".license");
if (!File.Exists(flagPath))
return false;
string stored = File.ReadAllText(flagPath, Encoding.UTF8).Trim();
string machineCode = GetLocalMachineCode();
string raw = machineCode + GetPrivateKey() + "LICENSED";
using (SHA256 sha256 = SHA256.Create())
{
byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(raw));
string expected = Convert.ToBase64String(hash);
return stored == expected;
}
}
catch
{
return false;
}
}
///
/// 清除授权标志(用于反激活/重新授权)
///
public static void ClearLicense()
{
try
{
string flagPath = Path.Combine(Application.StartupPath, ".license");
if (File.Exists(flagPath))
File.Delete(flagPath);
}
catch { }
}
///
/// 防调试检测——必须放在程序最开头调用!
/// 检测到调试器时不弹窗、直接退出,增加逆向难度
///
public static void CheckDebugger()
{
// 1. 检测是否有调试器附加
if (Debugger.IsAttached)
Environment.Exit(0);
// 2. 检测常见逆向/调试进程
string[] debugProcesses = { "dnspy", "ilspy", "x64dbg", "ollydbg",
"ida", "ida64", "windbg", "cheatengine", "de4dot" };
foreach (var proc in debugProcesses)
{
try
{
Process[] processes = Process.GetProcessesByName(proc);
if (processes.Length > 0)
Environment.Exit(0);
}
catch { }
}
// 3. 检测程序自身是否被篡改(检查文件 MD5)
CheckIntegrity();
}
///
/// 程序完整性校验(防止被修改后破解)
/// 注:需在编译后计算自身 MD5 填入 _expectedHash
///
private static void CheckIntegrity()
{
// ⚠️ 编译 Release 后,运行一次 GetSelfMd5() 获取哈希值,填到下面
// string expectedHash = "这里填编译后的 MD5";
// string actualHash = GetSelfMd5();
// if (actualHash != expectedHash)
// Environment.Exit(0);
}
///
/// 获取程序自身的 MD5(用于完整性校验配置)
///
public static string GetSelfMd5()
{
try
{
string path = Application.ExecutablePath;
using (FileStream fs = File.OpenRead(path))
using (MD5 md5 = MD5.Create())
{
byte[] hash = md5.ComputeHash(fs);
return BitConverter.ToString(hash).Replace("-", "").ToUpper();
}
}
catch { return ""; }
}
///
/// 防多开检测
///
public static void CheckSingleInstance()
{
string processName = Process.GetCurrentProcess().ProcessName;
Process[] processes = Process.GetProcessesByName(processName);
if (processes.Length > 1)
Environment.Exit(0);
}
///
/// 定时完整性巡检(建议放到 Timer 里,每 5-10 分钟执行一次)
///
public static void IntegrityPatrol()
{
// 再次检测调试器
if (Debugger.IsAttached)
Environment.Exit(0);
// 检测序列号是否还被授权
if (!IsLicensed())
Environment.Exit(0);
}
}
}