| using System; |
| using System.Management; |
| using System.Security.Cryptography; |
| using System.Text; |
|
|
| namespace KSTools.Licensing |
| { |
| |
| |
| |
| |
| public static class HardwareFingerprint |
| { |
| |
| |
| |
| |
| public static string GetHardwareId() |
| { |
| try |
| { |
| string hwInfo = ""; |
| |
| |
| string cpuId = GetCpuId(); |
| if (!string.IsNullOrEmpty(cpuId)) |
| { |
| hwInfo += cpuId; |
| } |
| |
| |
| string motherboardSerial = GetMotherboardSerial(); |
| if (!string.IsNullOrEmpty(motherboardSerial)) |
| { |
| hwInfo += motherboardSerial; |
| } |
| |
| |
| if (string.IsNullOrEmpty(hwInfo)) |
| { |
| hwInfo = GetMacAddress(); |
| } |
| |
| |
| using (var sha256 = SHA256.Create()) |
| { |
| var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(hwInfo + "KSTOOLS_SALT")); |
| string hashString = Convert.ToBase64String(hash); |
| |
| |
| hashString = hashString.Replace("+", "").Replace("/", "").Replace("=", ""); |
| return hashString.Length >= 32 ? hashString.Substring(0, 32) : hashString.PadRight(32, '0'); |
| } |
| } |
| catch (Exception ex) |
| { |
| |
| string fallback = Environment.MachineName + Environment.UserName + "KSTOOLS"; |
| using (var sha256 = SHA256.Create()) |
| { |
| var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(fallback)); |
| string hashString = Convert.ToBase64String(hash); |
| hashString = hashString.Replace("+", "").Replace("/", "").Replace("=", ""); |
| return hashString.Length >= 32 ? hashString.Substring(0, 32) : hashString.PadRight(32, '0'); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| private static string GetCpuId() |
| { |
| try |
| { |
| using (var searcher = new ManagementObjectSearcher("SELECT ProcessorId FROM Win32_Processor")) |
| { |
| foreach (ManagementObject obj in searcher.Get()) |
| { |
| return obj["ProcessorId"]?.ToString() ?? ""; |
| } |
| } |
| } |
| catch (Exception) |
| { |
| |
| } |
| |
| return ""; |
| } |
| |
| |
| |
| |
| |
| private static string GetMotherboardSerial() |
| { |
| try |
| { |
| using (var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard")) |
| { |
| foreach (ManagementObject obj in searcher.Get()) |
| { |
| string serial = obj["SerialNumber"]?.ToString() ?? ""; |
| |
| if (!string.IsNullOrEmpty(serial) && |
| serial != "To be filled by O.E.M." && |
| serial != "Default string" && |
| serial != "None") |
| { |
| return serial; |
| } |
| } |
| } |
| } |
| catch (Exception) |
| { |
| |
| } |
| |
| return ""; |
| } |
| |
| |
| |
| |
| |
| private static string GetMacAddress() |
| { |
| try |
| { |
| using (var searcher = new ManagementObjectSearcher("SELECT MACAddress FROM Win32_NetworkAdapter WHERE NetEnabled=true")) |
| { |
| foreach (ManagementObject obj in searcher.Get()) |
| { |
| string mac = obj["MACAddress"]?.ToString() ?? ""; |
| if (!string.IsNullOrEmpty(mac) && mac != "00:00:00:00:00:00") |
| { |
| return mac; |
| } |
| } |
| } |
| } |
| catch (Exception) |
| { |
| |
| } |
| |
| return Environment.MachineName; |
| } |
| |
| |
| |
| |
| |
| |
| public static bool IsValidHardwareId(string hardwareId) |
| { |
| return !string.IsNullOrEmpty(hardwareId) && |
| hardwareId.Length == 32 && |
| System.Text.RegularExpressions.Regex.IsMatch(hardwareId, @"^[A-Za-z0-9]+$"); |
| } |
| |
| |
| |
| |
| |
| public static string GetHardwareInfo() |
| { |
| try |
| { |
| var info = new StringBuilder(); |
| info.AppendLine($"電腦名稱: {Environment.MachineName}"); |
| info.AppendLine($"作業系統: {Environment.OSVersion}"); |
| info.AppendLine($"處理器架構: {Environment.ProcessorCount} 核心"); |
| info.AppendLine($"使用者: {Environment.UserName}"); |
| |
| |
| try |
| { |
| using (var searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_Processor")) |
| { |
| foreach (ManagementObject obj in searcher.Get()) |
| { |
| info.AppendLine($"處理器: {obj["Name"]}"); |
| break; |
| } |
| } |
| |
| using (var searcher = new ManagementObjectSearcher("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem")) |
| { |
| foreach (ManagementObject obj in searcher.Get()) |
| { |
| long memory = Convert.ToInt64(obj["TotalPhysicalMemory"]); |
| info.AppendLine($"記憶體: {memory / (1024 * 1024 * 1024)} GB"); |
| break; |
| } |
| } |
| } |
| catch |
| { |
| |
| } |
| |
| return info.ToString(); |
| } |
| catch (Exception ex) |
| { |
| return $"硬體資訊取得失敗: {ex.Message}"; |
| } |
| } |
| } |
| } |