生成一个唯一的机器ID

我需要编写一个函数来生成一个对于运行Windows操作系统的机器来说唯一的id。

目前,我正在使用WMI来查询各种硬件参数并将它们连接在一起,并将它们散列以获得唯一的ID。 我的问题是,我应该使用什么build议的参数? 目前,我正在使用bios \ cpu \ disk数据的组合来生成唯一的ID。 如果每个度量都有多个结果,那么我使用第一个结果。

但是,我遇到了一个问题,双启动到两个不同的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 

parsingSMBIOS并散列到任意长度。 有关所有可用的SMBIOS结构,请参阅PDF规范 。

要从Windows查询SMBIOS信息,您可以使用EnumSystemFirmwareEntriesEnumSystemFirmwareTablesGetSystemFirmwareTable

IIRC,来自CPUID指令的“唯一ID”从P3和更新版本被弃用。

我有同样的问题,并经过一些研究,我决定最好的是阅读registry项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography MachineGuid ,如@Agnusbuild议。 它是在操作系统安装过程中生成的,除非另外安装新的操作系统,否则不会更改。 根据操作系统版本的不同,它可能包含embedded式networking适配器MAC地址(加上一些其他的数字,包括随机数字)或伪随机数字,更新的操作系统版本(XP SP2之后,我相信,但不确定)的更高版本。 如果它是伪随机理论上可伪造的 – 如果两台机器具有相同的初始状态,包括实时时钟。 在实践中,这将是罕见的,但要知道,如果你期望它是一个安全的基础,可以攻击的硬核黑客。

当然,任何人都可以很容易地修改一个registry项来伪造一个机器的GUID,但是我发现这会破坏Windows的许多组件的正常运行,在大多数情况下,没有普通用户会这样做(再次,小心对于硬核黑客)。

通过我们的许可工具,我们考虑以下组件

  • MAC地址
  • CPU(不是序列号,但实际的CPUconfiguration文件,如步进和型号)
  • 系统驱动器序列号(不是卷标)
  • 记忆
  • CD-ROM模型和供应商
  • video卡模型和供应商
  • IDE控制器
  • SCSI控制器

但是,我们不仅仅是对组件进行哈希处理,而是创build一个通过/失败系统,我们创build了一个可比较的指纹 ,可以用来确定两台机器configuration文件的不同。 如果差异评级高于指定的容差,则要求用户再次激活。

我们发现,在过去的8年中,成千上万的最终用户安装使用了这种组合,即使对于虚拟机和克隆的操作系统安装,该组合也能很好地提供可靠的唯一机器ID。

我讨厌成为那个说“你只是做错了”的人(我总是讨厌那个人),但是…

是否必须重复生成独特的机器? 你可以分配标识符还是公钥/私钥? 也许如果你可以生成和存储的价值,你可以从两个操作系统安装在同一磁盘上访问它?

您可能已经探索过这些选项,但它们并不适合您,但是如果没有的话,这是需要考虑的。

如果不是用户信任问题,则可以使用MAC地址。

那么使用处理器的UniqueID呢?

您应该考虑使用网卡上的MAC地址(如果存在)。 这些通常是独特的,但可以捏造。 我已经使用了根据您的networking适配器MAC地址生成许可证文件的软件,所以它被认为是区分计算机的一种相当可靠的方法。

对于我的一个应用程序,如果它是非域计算机,或者域计算机的域计算机帐户SID,则使用计算机名称。 Mark Russinovich在这篇博客文章Machine SID中谈到:

如果分布式应用程序使用机器SID来唯一标识计算机,则SID复制将是一个问题的最后一种情况。 没有Microsoft软件这样做,并且以这种方式使用机器SID不适用于所有DC都具有相同机器SID的事实。 依赖唯一计算机标识的软件要么使用计算机名称,要么使用计算机域SID(域中的计算机帐户的SID)。

您可以通过LDAP或System.DirectoryServices访问域计算机帐户SID。

在我的程序中,我首先检查terminal服务器,并使用WTSClientHardwareId。 否则,本地PC的MAC地址应该足够了。

如果您真的想使用您提供的属性列表, Clockspeed NameDriverVersionClockspeed等,因为它可能取决于操作系统。 尝试在两个操作系统上输出相同的信息,并忽略其中的差异。

为什么不使用网卡的MAC地址?

也许作弊一点点,但机器的以太网适配器的MAC地址很less改变,如今这些主板改变。

你可以拉某种制造商的序列号或服务标签?

我们的商店是一家戴尔商店,所以我们使用每台机器独有的服务标签来识别它们。 我知道它可以从BIOS中查询,至less在Linux中,但我不知道如何在Windows中做到这一点。

硬件序列号提取器(CPU,RAM,HDD,BIOS)

查找一个选项的CPUID。 多CPU系统可能存在一些问题。

试试这个,它给出了一个唯一的硬盘ID: Delphi 7-2010的DiskId32端口 。