生成唯一的机器ID


104

我需要编写一个函数,该函数生成的ID对于运行Windows OS的给定计算机是唯一的。

当前,我正在使用WMI查询各种硬件参数,并将它们连接在一起并对其进行哈希处理以得出唯一的ID。我的问题是,我应该使用哪些建议的参数?目前,我正在使用bios \ cpu \ disk数据的组合来生成唯一ID。如果每个指标有多个结果,则使用第一个结果。

但是,我遇到了一个问题,即双重引导进入2个不同Windows操作系统的计算机在每个OS上生成不同的站点代码,理想情况下不会发生这种情况。

作为参考,这些是我当前正在使用的指标:

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

Answers:


25

自己解析SMBIOS并将其散列为任意长度。有关所有可用的SMBIOS结构,请参见PDF规范

要查询从Windows的SMBIOS信息你可以使用EnumSystemFirmwareEntriesEnumSystemFirmwareTablesGetSystemFirmwareTable

IIRC,P3及更高版本不建议使用CPUID指令中的“唯一ID”。


14
请注意,这些功能至少需要Windows Vista,Windows XP Professional x64 Edition,Windows Server 2008或Windows Server 2003 SP1。
jcoffland 2011年

33
一个不做我做的笔记,叫做GetSystemFirmwareTable('RSMB'...); 并散列整个SMBIOSTableData缓冲区。直到我遇到一个工作站,该工作站将CPU的内部温度写入该表之前,它的工作效果非常好,这意味着我的唯一ID每隔几秒钟就会更改一次。
Thomas

此解决方案有可用的源代码吗?
Just Shadow

@Thomas,您最终选择了哪种解决方案?
史密斯

@Smith我的目标是一个小的8个字符的ID。阅读规范后,我决定了哪些字段可能会有所不同,并排除了它们。然后,多年来,我修剪掉了更多不是机器常数的字段。最后,我最终存储了我用作输入的原始数据的加密副本,并创建了一个closeEnough函数,以便如果它仅在2个字段中发生变化,我将接受不匹配的ID。我还在哈希中包含有关处理器和系统硬盘驱动器的详细信息,因为早期我在相同系统之间发生冲突。
托马斯(Thomas)

72

我遇到了同样的问题,经过一番研究,我决定最好的方法是按@Agnus的建议读MachineGuid入注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography。它是在操作系统安装期间生成的,除非您进行另一次全新的操作系统安装,否则不会更改。根据操作系统版本的不同,它可能包含嵌入的网络适配器MAC地址(加上一些其他数字,包括随机数)或伪随机数,而对于较新的OS版本则是更高版本(相信XP SP2之后)。如果从理论上讲是伪随机的,则可以伪造-如果两台计算机的初始状态相同,包括实时时钟。在实践中,这种情况很少见,但是请注意,如果您希望它是可以被铁杆黑客攻击的安全基础。

当然,任何人都可以轻松更改注册表项以伪造计算机GUID,但是我发现这会破坏Windows如此众多组件的正常运行,在大多数情况下,没有普通用户会这样做(再次,当心适用于顽固的黑客)。


6
我认为,您可以使用KEY_WOW64_64KEY标志来确保始终获得“真实”版本的注册表项。
科伦

13
如果克隆驱动器映像,它将保持不变。因此,这根本不是防篡改的,也不是非常不安全的。
bitbonk 2011年

19
为了澄清这一点,当我在软件中使用DRM措施时,我的主要目标是防止人们制造裂缝,使“专业”海盗能够不受限制地出售软件的非法副本。我并不担心偶尔的黑客会克隆他朋友的驱动器只是为了能够使用我的软件。在这种情况下,这些人通常比金钱拥有更多的时间,反正也不会为此付出代价。如果该软件的价格为$ 100,而您的工资超过$ 50 / h,您只需为此付费。麻烦将花费比2小时更多的时间。
Fabio Ceconello 2011年

7
特别是,在通过克隆主计算机映像安装Windows的环境中,MachineGuid对所有它们都是相同的。
nandhp

8
如果您使用sysprep&all正确合法地这样做,则不会。对于那些盗版Windows副本并“只是克隆”的用户,这是另一回事。但是无论如何,它们都不会轻易被阻止。
Fabio Ceconello 2012年

34

使用我们的许可工具,我们考虑以下组件

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

但是,我们不仅创建哈希表并创建通过/失败系统,还创建了可比较的指纹,该指纹可用于确定两个计算机配置文件的差异。如果差值等级高于指定的公差,则要求用户再次激活。

我们发现,在过去的8年中,数十万个最终用户安装使用了该组合,可以很好地提供可靠的唯一计算机ID,甚至适用于虚拟机和克隆的OS安装。


1
您如何确定使用哪个MAC地址?一台机器可以具有多个NIC,并且这些NIC是动态添加的(通过applet连接到新的VPN将添加虚拟NIC)。有些是虚拟的,具有以太网类型,很难识别为虚拟。其他人则根据网络状况(wifi)上/下
Marek

我们使用所有物理NIC-虚拟NICS,蓝牙等除外。它们全部组合在一起以创建统一的哈希。
Paul Alexander

为什么建议您不要使用CPU序列号?
Mojtaba Rezaeian '16

3
多年来,Intel芯片中未启用CPU序列号。系统调用仍然存在,但不会返回稳定值。我不记得它返回什么-所有机器的虚拟数据或相同值。无论哪种方式,它都不是可靠的硬件指标。
保罗·亚历山大

1
@PaulAlexander您所引用的工具可以验证您提到的所有参数,或者其中很少几个可以使用?因为如今的系统通常不包含CD-ROM
所以FaisanHussainRabbani的发布时间为

3

仅使用处理器的UniqueID怎么办?


14
这些天不是折旧的财产吗?
杰克·威尔逊

15
也许他的意思是“不赞成使用”……CPU制造商开始将唯一ID放在一个阶段,但是由于对隐私问题的强烈反对,他们又停了下来。因此,您会发现其中一些具有唯一的ID,但大多数现代CPU却没有。
2011年

1
作为参考,只有一小批奔腾III具有可读取的CPU序列号。虽然更高版本具有序列号,但默认情况下它是禁用的。奔腾IV和更高版本的CPU根本不支持它。
保罗·亚历山大

2

我讨厌成为一个说“你做错了”的人(我一直讨厌那个人;)但是...

是否必须为唯一的机器重复生成?您能分配标识符还是做一个公钥/私钥?也许如果您可以生成并存储该值,则可以从同一磁盘上的两个OS安装中访问它?

您可能已经探索了这些选项,但它们对您不起作用,但是如果没有,则需要考虑一些问题。

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


5
如果机器没有网卡,则MAC地址将不起作用。
布赖恩

7
@Brian-您真的需要一个唯一的值来识别没有网卡的计算机吗?机器上有卡似乎很安全。
rom09年

1

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


6
不,不是。许多制造商允许您更改它们。这在使用群集时非常有用,因为某些供应商为您提供的所有计算机都具有相同的MAC地址(几年前我们曾遇到过此问题)。
gizmo

在许多情况下,这是个有效的主意,问题不指定欺骗性或离线性-如果您想在网络中进行识别,通常希望生成唯一的ID
Hurda 2012年

同一台机器上可能有多个网络设备。您不能保证总是以相同的顺序检测到它们,或者在某些时候不会将它们替换掉。最好使用一些可能更永久的硬件。
Agi Hammerthief

1

对于我的一个应用程序,我要么使用计算机名称(如果它是非域计算机),要么使用域计算机的域计算机帐户SID。马克·鲁西诺维奇(Mark Russinovich)在此博客文章Machine SID中进行了讨论

SID复制将成为问题的最后一种情况是,分布式应用程序是否使用计算机SID来唯一标识计算机。没有Microsoft软件会这样做,并且以这种方式使用计算机SID并不仅仅因为所有DC都具有相同的计算机SID的事实。依赖于唯一计算机身份的软件将使用计算机名称或计算机域SID(域中计算机帐户的SID)。

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


1

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

如果您确实要使用提供的属性列表,请忽略诸如NameDriverVersion,之类的内容Clockspeed,因为它可能取决于操作系统。尝试在两个操作系统上输出相同的信息,而忽略两者之间的差异。



0

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


14
MAC地址是伪造的
亨利乙

在许多情况下,这是一个有效的主意,问题不指定欺骗性或离线性-如果您想在网络中进行识别,通常希望生成唯一的ID
Hurda 2012年

0

也许有些作弊,但是如今,如果不更改主板,机器以太网适配器的MAC地址很少会更改。


许多制造商允许您更改它们。这在使用群集时非常有用,因为某些供应商为您提供的所有计算机都具有相同的MAC地址(几年前我们曾遇到过此问题)。
gizmo

1
MAC绝对不可靠,因为它可以很容易地更改(仅适用于google搜索,您会看到很多免费的工具正在执行此操作)。WMI也是一样。
InTheNameOfScience 2015年

0

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

我们的商店是戴尔的商店,因此我们使用每台机器唯一的服务标签来识别它们。我知道至少在Linux中可以从BIOS中查询它,但是我不知道如何在Windows中立即使用它。


0

我还有一个额外的约束,我使用的是.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

-1

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.