using System.IO; using System.Management; using System.Security.Cryptography; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using Melskin.Controls; namespace KeyGen; /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow { private static string _privateKey = string.Empty; public MainWindow() { InitializeComponent(); } private void LicenseClick(object sender, RoutedEventArgs e) { _privateKey = PrivateKeyTextBox.Text; LicenseManager.PublicKey = PublicKeyTextBox.Text; DateTime issueDate = DateTime.Now; //DateTime expiryDate = issueDate.AddYears(1); DateTime expiryDate = ExpiryDatePicker.DisplayDate; if (expiryDate < issueDate) { MessageBox.Show("授权到期时间有误,应比发码日期晚"); return; } string mCode = MachineCodeTextBox.Text.Trim().ToUpper(); if (string.IsNullOrEmpty(mCode)) { MessageBox.Show("请先获取机器码"); return; } string key = CreateLicense(mCode, issueDate, expiryDate); LicenseTextBox.Text = key; Clipboard.SetText(key); MessageBox.Show("激活码已复制!"); } private string CreateLicense(string machineCode, DateTime issue, DateTime expiry) { string issueStr = issue.ToString("yyyyMMdd"); string expiryStr = expiry.ToString("yyyyMMdd"); // 签名原始数据:机器码 + 发码日期 + 过期日期 string dataToSign = $"{machineCode}|{issueStr}|{expiryStr}"; using (var rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(_privateKey); var formatter = new RSAPKCS1SignatureFormatter(rsa); formatter.SetHashAlgorithm("SHA256"); byte[] dataBytes = Encoding.UTF8.GetBytes(dataToSign); using (var sha = SHA256.Create()) { byte[] hash = sha.ComputeHash(dataBytes); string signature = Convert.ToBase64String(formatter.CreateSignature(hash)); // 最终格式:签名|机器码|发码日期|过期日期 return $"{signature}|{machineCode}|{issueStr}|{expiryStr}"; } } } private void GenerateKeyClick(object sender, RoutedEventArgs e) { using var rsa = new RSACryptoServiceProvider(2048); PublicKeyTextBox.Text = rsa.ToXmlString(false); // 放在插件里 PrivateKeyTextBox.Text = rsa.ToXmlString(true); // 自己妥善保存 } private void ValidateClick(object sender, RoutedEventArgs e) { var result = LicenseManager.Validate(); MessageBox.Show(result.msg); } private void RemoveLicenseClick(object sender, RoutedEventArgs e) { LicenseManager.RemoveLicense(); MessageBox.Show("授权已注销"); } private void ActivateClick(object sender, RoutedEventArgs e) { LicenseManager.Activate(LicenseTextBox.Text); } private void MachineCodeClick(object sender, RoutedEventArgs e) { MachineCodeTextBox.Text = HardwareInfo.GetMachineCode(); } private void SaveKeysClick(object sender, RoutedEventArgs e) { VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog(); if (dialog.ShowDialog()) { string publicKeyPath = System.IO.Path.Combine(dialog.SelectedPath, "PublicKey.txt"); File.WriteAllText(publicKeyPath, PublicKeyTextBox.Text); string privateKeyPath = System.IO.Path.Combine(dialog.SelectedPath, "PrivateKey.txt"); File.WriteAllText(privateKeyPath, PrivateKeyTextBox.Text); MessageBox.Show($"公私密钥已保存到:{dialog.SelectedPath}"); } } private void SaveLicenseClick(object sender, RoutedEventArgs e) { VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog(); if (dialog.ShowDialog()) { string path = System.IO.Path.Combine(dialog.SelectedPath, "license.txt"); File.WriteAllText(path, LicenseTextBox.Text); MessageBox.Show($"激活码已保存到:{path}"); } } } public static class HardwareInfo { public static string GetMachineCode() { try { string cpu = GetWmiInfo("Win32_Processor", "ProcessorId"); string board = GetWmiInfo("Win32_BaseBoard", "SerialNumber"); string disk = GetWmiInfo("Win32_PhysicalMedia", "SerialNumber"); // 物理硬盘序列号 // 拼接并哈希,只取前16位,方便复制 string raw = $"{cpu}@{board}@{disk}"; using (var sha = SHA256.Create()) { byte[] bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(raw)); return BitConverter.ToString(bytes).Replace("-", "").Substring(0, 16).ToUpper(); } } catch { return "ERROR-HARDWARE-ID"; } } private static string GetWmiInfo(string table, string prop) { try { using (var mc = new ManagementClass(table)) foreach (var mo in mc.GetInstances()) { string val = mo[prop]?.ToString(); if (!string.IsNullOrWhiteSpace(val)) return val.Trim(); } } catch { } return "UNKNOWN"; } }