生成唯一的机器 ID
-
01-07-2019 - |
题
我需要编写一个函数来生成一个对于运行 Windows 操作系统的给定机器来说唯一的 id。
目前,我正在使用 WMI 查询各种硬件参数,并将它们连接在一起并对它们进行哈希处理以得出唯一的 id。我的问题是,我应该使用哪些建议参数?目前,我使用 BIOS\CPU\磁盘数据的组合来生成唯一 ID。如果每个指标有多个结果,则使用第一个结果。
但是,我遇到了一个问题,即双启动到 2 个不同 Windows 操作系统的计算机会在每个操作系统上生成不同的站点代码,这在理想情况下应该不会发生。
作为参考,这些是我当前使用的指标:
Win32_Processor:UniqueID,ProcessorID,Name,Manufacturer,MaxClockSpeed
Win32_BIOS:Manufacturer
Win32_BIOS:SMBIOSBIOSVersion,IdentificationCode,SerialNumber,ReleaseDate,Version
Win32_DiskDrive:Model, Manufacturer, Signature, TotalHeads
Win32_BaseBoard:Model, Manufacturer, Name, SerialNumber
Win32_VideoController:DriverVersion, Name
解决方案
解析 SMBIOS 你自己并将其散列到任意长度。请参阅 PDF规格 适用于所有可用的 SMBIOS 结构。
要从 Windows 查询 SMBIOS 信息,您可以使用 EnumSystemFirmwareEntries
, EnumSystemFirmwareTables
和 GetSystemFirmwareTable
.
IIRC,CPUID 指令中的“唯一 ID”从 P3 及更高版本中已弃用。
其他提示
我遇到了同样的问题,经过一番研究后,我决定最好的方法是阅读 MachineGuid
在注册表项中 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
, ,正如@Agnus建议的那样。它是在操作系统安装期间生成的,除非您重新安装另一个操作系统,否则不会更改。根据操作系统版本,它可能包含嵌入的网络适配器 MAC 地址(加上一些其他数字,包括随机数)或伪随机数,后者适用于较新的操作系统版本(我相信在 XP SP2 之后,但不确定)。如果它是伪随机的,理论上它可以被伪造 - 如果两台机器具有相同的初始状态,包括实时时钟。实际上,这种情况很少见,但如果您希望它成为可能受到铁杆黑客攻击的安全基础,请注意。
当然,任何人都可以轻松地更改注册表项来伪造机器 GUID,但我发现这会破坏 Windows 的许多组件的正常运行,在大多数情况下,普通用户不会这样做(再次提醒,请注意)对于铁杆黑客来说)。
我讨厌成为那个说“你只是做错了”的人(我一直讨厌那个人;)但是......
是否必须为唯一的机器重复生成?您可以只分配标识符或执行公钥/私钥吗?也许如果您可以生成并存储该值,您就可以从同一磁盘上安装的两个操作系统访问它?
您可能已经探索过这些选项,但它们并不适合您,但如果不适合,则需要考虑。
如果不是用户信任问题,您可以只使用 MAC 地址。
只使用处理器的 UniqueID 怎么样?
您应该考虑使用网卡上的 MAC 地址(如果存在)。这些通常是独特的,但可以伪造。我使用过根据网络适配器 MAC 地址生成许可证文件的软件,因此它被认为是区分计算机的相当可靠的方法。
对于我的一个应用程序,如果是非域计算机,则使用计算机名称;如果是域计算机,则使用域计算机帐户 SID。马克·鲁西诺维奇 (Mark Russinovich) 在这篇博文中谈到了这一点, 机器SID:
SID 重复成为问题的最后一种情况是分布式应用程序使用计算机 SID 来唯一标识计算机。没有 Microsoft 软件这样做,并且以这种方式使用计算机 SID 并不能仅仅因为所有 DC 都具有相同的计算机 SID。依赖唯一计算机标识的软件使用计算机名称或计算机域 SID(域中计算机帐户的 SID)。
您可以通过LDAP或访问域机器帐户SID System.DirectoryServices
.
在我的程序中,我首先检查终端服务器并使用 WTSClientHardwareId。否则本地 PC 的 MAC 地址应该足够了。
如果您确实想使用您提供的属性列表,请忽略以下内容 Name
和 DriverVersion
, Clockspeed
, , ETC。因为它可能依赖于操作系统。尝试在两个操作系统上输出相同的信息,并忽略不同的信息。
有一个库可用于获取硬件特定信息: 硬件序列号提取器(CPU、RAM、HDD、BIOS)
为什么不使用网卡的 MAC 地址呢?
也许有点作弊,但现在机器以太网适配器的 MAC 地址很少在主板不改变的情况下改变。
您可以获取某种制造商序列号或服务标签吗?
我们的商店是戴尔商店,因此我们使用每台机器唯一的服务标签来识别它们。我知道它可以从 BIOS 中查询,至少在 Linux 中是这样,但我不知道如何在 Windows 中执行此操作。
我有一个额外的限制,我使用的是 .net express,所以我无法使用标准硬件查询机制。所以我决定使用power shell来进行查询。完整的代码如下所示:
Private Function GetUUID() As String
Dim GetDiskUUID As String = "get-wmiobject Win32_ComputerSystemProduct | Select-Object -ExpandProperty UUID"
Dim X As String = ""
Dim oProcess As New Process()
Dim oStartInfo As New ProcessStartInfo("powershell.exe", GetDiskUUID)
oStartInfo.UseShellExecute = False
oStartInfo.RedirectStandardInput = True
oStartInfo.RedirectStandardOutput = True
oStartInfo.CreateNoWindow = True
oProcess.StartInfo = oStartInfo
oProcess.Start()
oProcess.WaitForExit()
X = oProcess.StandardOutput.ReadToEnd
Return X.Trim()
End Function
查找 CPUID 以获得一个选项。多 CPU 系统可能会出现一些问题。
试试这个,它给出了一个唯一的硬盘 ID: Delphi 7-2010 的 DiskId32 端口.