56 lines
1.6 KiB
Python
56 lines
1.6 KiB
Python
"""
|
|
HWID Generator
|
|
==============
|
|
Generates a stable hardware fingerprint for this machine using:
|
|
- Windows MachineGuid (most stable, survives most software changes)
|
|
- CPU Processor ID (hardware-level, very stable)
|
|
|
|
Returns a SHA-256 hex digest. Never changes unless hardware changes.
|
|
"""
|
|
|
|
import hashlib
|
|
import subprocess
|
|
import winreg
|
|
|
|
|
|
def get_hwid() -> str:
|
|
"""Return a stable SHA-256 HWID string for the current machine."""
|
|
components = []
|
|
|
|
# Windows MachineGuid — set once at OS install, very stable
|
|
try:
|
|
key = winreg.OpenKey(
|
|
winreg.HKEY_LOCAL_MACHINE,
|
|
r"SOFTWARE\Microsoft\Cryptography"
|
|
)
|
|
guid, _ = winreg.QueryValueEx(key, "MachineGuid")
|
|
winreg.CloseKey(key)
|
|
components.append(f"guid:{guid}")
|
|
except Exception:
|
|
pass
|
|
|
|
# CPU Processor ID — hardware-level identifier
|
|
try:
|
|
result = subprocess.run(
|
|
["wmic", "cpu", "get", "ProcessorId", "/value"],
|
|
capture_output=True, text=True, timeout=5
|
|
)
|
|
for line in result.stdout.splitlines():
|
|
line = line.strip()
|
|
if line.startswith("ProcessorId=") and "=" in line:
|
|
cpu_id = line.split("=", 1)[1].strip()
|
|
if cpu_id:
|
|
components.append(f"cpu:{cpu_id}")
|
|
break
|
|
except Exception:
|
|
pass
|
|
|
|
if not components:
|
|
raise RuntimeError(
|
|
"Could not generate HWID. "
|
|
"This application requires Windows and access to system information."
|
|
)
|
|
|
|
raw = "|".join(components)
|
|
return hashlib.sha256(raw.encode("utf-8")).hexdigest()
|