/** * 设备指纹生成 - 跨平台 (v3.0.4: Win11 兼容) * 基于: 主机名 + 用户名 + CPU ID + 磁盘序列号 + 架构 * 输出 SHA-256 hex (64 字符) * * v3.0.4: Win11 22H2+ 默认移除 wmic.exe, 改为三级 fallback: * 1. PowerShell CIM cmdlet (Win10/Win11 通用) * 2. wmic.exe (老 Win10 残留) * 3. 注册表 MachineGuid (任何 Windows 都有, 兜底) */ const crypto = require("crypto"); const os = require("os"); const fs = require("fs"); const { execSync } = require("child_process"); function safeExec(cmd) { try { return execSync(cmd, { encoding: "utf8", timeout: 5000, windowsHide: true }).toString(); } catch { return ""; } } // Windows 三级 fallback 查询 function winQuery(cimExpr, wmicArgs, regFallback) { // 1. PowerShell CIM (最优先 - Win10/11 都原生支持) const ps = safeExec(`powershell -NoProfile -NonInteractive -Command "${cimExpr.replace(/"/g, '\\"')}"`); const psResult = ps.replace(/[\r\n]/g, "").trim(); if (psResult && psResult.length > 0) return psResult; // 2. wmic.exe fallback (Win11 22H2+ 可能被移除, 先检测存在性) const wmic = "C:\\Windows\\System32\\wbem\\wmic.exe"; if (fs.existsSync(wmic)) { const out = safeExec(`"${wmic}" ${wmicArgs}`); const lines = out.split(/\r?\n/).filter(l => /=.+/.test(l)); for (const l of lines) { const v = l.split("=")[1]?.trim(); if (v && v.length > 0) return v; } } // 3. 注册表兜底 (MachineGuid — 任何 Windows 一装系统就存在, 重装才变) if (regFallback) { const regOut = safeExec(`reg query "${regFallback.key}" /v "${regFallback.value}"`); const m = regOut.match(/REG_SZ\s+(.+)/i); if (m) return m[1].trim(); } return ""; } function cpuId() { if (process.platform === "win32") { return winQuery( "(Get-CimInstance Win32_Processor).ProcessorId", "cpu get ProcessorId /value", { key: "HKLM\\SOFTWARE\\Microsoft\\Cryptography", value: "MachineGuid" } ); } if (process.platform === "darwin") { const out = safeExec("system_profiler SPHardwareDataType"); const m = out.match(/Hardware UUID:\s+([A-F0-9-]+)/); return m ? m[1] : ""; } // Linux return safeExec("cat /etc/machine-id 2>/dev/null").trim(); } function diskSerial() { if (process.platform === "win32") { return winQuery( "(Get-CimInstance Win32_DiskDrive | Where-Object { $_.SerialNumber } | Select-Object -First 1).SerialNumber", "diskdrive get SerialNumber /value", { key: "HKLM\\SOFTWARE\\Microsoft\\Cryptography", value: "MachineGuid" } ); } if (process.platform === "darwin") { const out = safeExec("diskutil info /"); const m = out.match(/Volume UUID:\s+([A-F0-9-]+)/); return m ? m[1] : ""; } return safeExec("lsblk -no SERIAL 2>/dev/null | head -1").trim(); } function fingerprint() { const raw = [ os.hostname(), os.userInfo().username, cpuId(), diskSerial(), os.arch() ].join("::"); return crypto.createHash("sha256").update(raw).digest("hex"); } module.exports = { fingerprint }; if (require.main === module) { // 直接运行时打印指纹 console.log(fingerprint()); }