更新
This commit is contained in:
119
KeyGen/LicenseManager.cs
Normal file
119
KeyGen/LicenseManager.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System.Text;
|
||||
|
||||
namespace KeyGen
|
||||
{
|
||||
internal class LicenseManager
|
||||
{
|
||||
// 【重要】替换为你生成的公钥
|
||||
public static string PublicKey = @"<RSAKeyValue><Modulus>rd5+EjU6QxaTY/AalU9g6ugAquN0ahJSgeahnf2CrfvUAWFNJ+SH7Qr0RcvOTyAbWfvLWoBDACKaPsg+8nRQcO3EZdFyjJ9oycLNrw38+gSB2+/79Axys/8MHtSXVUw9WN2e9LxeHOQGtcaoSsp+bPGaXswthovQ2CkvBTmCokcAOX6UaR7Av4npaXyEoGCUsZLEiSydMsNbQ+wLsumVg1H2o/cpkO0s4DiJHoF66zUuxA+pYSjSCn5KTUsOemf+gBsob6Sw+7WOToyiOkMdO9Op6esf8yL7DJ1Yd40XaKd5IeLQmEX/b+n1EV2JEkGO0p9q9MQRp6NrEc9LvfMJWQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
|
||||
|
||||
private static string RegPath = @$"Software\{Assembly.GetExecutingAssembly().GetName()}\License";
|
||||
/// <summary>
|
||||
/// 校验结果枚举
|
||||
/// </summary>
|
||||
public enum AuthStatus { Valid, Expired, HardwareMismatch, TimeTampered, InvalidSignature, NoLicense }
|
||||
/// <summary>
|
||||
/// 核心验证方法
|
||||
/// </summary>
|
||||
public static (AuthStatus status, string msg) Validate()
|
||||
{
|
||||
string licenseKey = LoadReg("Key");
|
||||
if (string.IsNullOrEmpty(licenseKey)) return (AuthStatus.NoLicense, "未激活");
|
||||
|
||||
try
|
||||
{
|
||||
// 格式:签名|机器码|发码日期|过期日期
|
||||
var parts = licenseKey.Split('|');
|
||||
if (parts.Length != 4) return (AuthStatus.InvalidSignature, "授权格式错误");
|
||||
|
||||
string signature = parts[0];
|
||||
string mCode = parts[1];
|
||||
string issueDateStr = parts[2];
|
||||
string expiryDateStr = parts[3];
|
||||
|
||||
// 1. 硬件校验
|
||||
if (mCode != HardwareInfo.GetMachineCode())
|
||||
return (AuthStatus.HardwareMismatch, "机器码不匹配,请联系管理员");
|
||||
|
||||
// 2. RSA 签名校验 (防止篡改日期)
|
||||
string dataVerify = $"{mCode}|{issueDateStr}|{expiryDateStr}";
|
||||
if (!VerifyRSA(dataVerify, signature))
|
||||
return (AuthStatus.InvalidSignature, "非法授权 (签名无效)");
|
||||
|
||||
// 3. 时间逻辑校验
|
||||
DateTime issueDate = DateTime.ParseExact(issueDateStr, "yyyyMMdd", null);
|
||||
DateTime expiryDate = DateTime.ParseExact(expiryDateStr, "yyyyMMdd", null);
|
||||
DateTime now = TimeHelper.GetTrustedTime(); // 获取可信时间
|
||||
|
||||
// 3.1 检查是否早于发码日期 (防极度回滚)
|
||||
if (now < issueDate)
|
||||
return (AuthStatus.TimeTampered, "系统时间异常:早于授权发码时间");
|
||||
|
||||
// 3.2 检查上次运行记录 T (防短期回滚)
|
||||
long lastRunTicks = 0;
|
||||
long.TryParse(LoadReg("T"), out lastRunTicks);
|
||||
if (lastRunTicks > 0)
|
||||
{
|
||||
DateTime lastRun = new DateTime(lastRunTicks);
|
||||
// 允许1小时的误差
|
||||
if (now < lastRun.AddHours(-1))
|
||||
return (AuthStatus.TimeTampered, "系统时间异常:检测到时间倒流");
|
||||
}
|
||||
|
||||
// 3.3 检查过期
|
||||
if (now.Date > expiryDate.Date)
|
||||
return (AuthStatus.Expired, $"授权已于 {expiryDate:yyyy-MM-dd} 到期");
|
||||
|
||||
// --- 验证通过 ---
|
||||
SaveReg("T", now.Ticks.ToString()); // 更新痕迹
|
||||
return (AuthStatus.Valid, $"授权有效,到期时间为{expiryDate:yyyy-MM-dd}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return (AuthStatus.InvalidSignature, "授权解析异常");
|
||||
}
|
||||
}
|
||||
|
||||
// 保存激活码
|
||||
public static void Activate(string keyInput)
|
||||
{
|
||||
SaveReg("Key", keyInput);
|
||||
}
|
||||
|
||||
// RSA 验签辅助
|
||||
private static bool VerifyRSA(string data, string signature)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var rsa = new RSACryptoServiceProvider())
|
||||
{
|
||||
rsa.FromXmlString(PublicKey);
|
||||
var formatter = new RSAPKCS1SignatureDeformatter(rsa);
|
||||
formatter.SetHashAlgorithm("SHA256");
|
||||
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
|
||||
byte[] signBytes = Convert.FromBase64String(signature);
|
||||
using (var sha = SHA256.Create())
|
||||
{
|
||||
return formatter.VerifySignature(sha.ComputeHash(dataBytes), signBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
#region 注册表底层
|
||||
private static void SaveReg(string key, string val)
|
||||
{
|
||||
using (var r = Registry.CurrentUser.CreateSubKey(RegPath)) r.SetValue(key, val);
|
||||
}
|
||||
private static string LoadReg(string key)
|
||||
{
|
||||
using (var r = Registry.CurrentUser.OpenSubKey(RegPath)) return r?.GetValue(key)?.ToString();
|
||||
}
|
||||
public static void RemoveLicense()
|
||||
{
|
||||
using (var r = Registry.CurrentUser.OpenSubKey(RegPath, true)) r?.DeleteValue("Key", false);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
46
KeyGen/TimeHelper.cs
Normal file
46
KeyGen/TimeHelper.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace KeyGen
|
||||
{
|
||||
internal static class TimeHelper
|
||||
{
|
||||
public static DateTime GetTrustedTime()
|
||||
{
|
||||
// 1. 尝试网络时间 (3秒超时)
|
||||
try
|
||||
{
|
||||
var request = WebRequest.Create("http://www.baidu.com"); // 或 microsoft.com
|
||||
request.Method = "HEAD";
|
||||
request.Timeout = 3000;
|
||||
using (var response = request.GetResponse())
|
||||
{
|
||||
string dateStr = response.Headers["Date"];
|
||||
if (DateTime.TryParseExact(dateStr, "ddd, dd MMM yyyy HH:mm:ss 'GMT'",
|
||||
CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTime netTime))
|
||||
return netTime.ToLocalTime();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// 2. 尝试文件系统痕迹校验 (防断网改时间)
|
||||
DateTime localNow = DateTime.Now;
|
||||
try
|
||||
{
|
||||
// 获取系统目录和临时目录的最后修改时间
|
||||
DateTime t1 = new DirectoryInfo(Environment.SystemDirectory).LastWriteTime;
|
||||
DateTime t2 = new DirectoryInfo(Path.GetTempPath()).LastWriteTime;
|
||||
DateTime latestFileTime = t1 > t2 ? t1 : t2;
|
||||
|
||||
// 如果本地时间比系统文件时间还要早超过24小时,判定为作弊
|
||||
if (localNow < latestFileTime.AddHours(-24))
|
||||
{
|
||||
return latestFileTime; // 强制使用文件时间
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// 3. 兜底
|
||||
return localNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
Title="DaVinci Resolve drfx 字体替换"
|
||||
Width="1000"
|
||||
mc:Ignorable="d"
|
||||
x:Class="DrfxFontFixer.MainWindow"
|
||||
x:Class="ShrlAlgoStudio.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
@@ -16,7 +16,7 @@ using System.Windows.Media;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DrfxFontFixer
|
||||
namespace ShrlAlgoStudio
|
||||
{
|
||||
public class FullMapping : INotifyPropertyChanged
|
||||
{
|
||||
12
ShrlAlgoStudio/MainWindow.xaml
Normal file
12
ShrlAlgoStudio/MainWindow.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<Window x:Class="ShrlAlgoStudio.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ShrlAlgoStudio"
|
||||
mc:Ignorable="d"
|
||||
Title="MainWindow" Height="450" Width="800">
|
||||
<Grid>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
12
ShrlAlgoStudio/MainWindow.xaml.cs
Normal file
12
ShrlAlgoStudio/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace ShrlAlgoStudio
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
ShrlAlgoStudio/ShrlAlgoStudio.csproj
Normal file
16
ShrlAlgoStudio/ShrlAlgoStudio.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<LangVersion>13.0</LangVersion>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NeoUI\Melskin\Melskin.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user