windows 生成唯一的机器 ID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/99880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 05:19:54  来源:igfitidea点击:

Generating a unique machine id

windowswinapiwmiuniqueidentifier

提问by HS.

I need to write a function that generates an id that is unique for a given machine running a Windows OS.

我需要编写一个函数来生成一个 ID,该 ID 对于运行 Windows 操作系统的给定机器是唯一的。

Currently, I'm using WMI to query various hardware parameters and concatenate them together and hash them to derive the unique id. My question is, what are the suggested parameters I should use? Currently, I'm using a combination of bios\cpu\disk data to generate the unique id. And am using the first result if multiple results are there for each metric.

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

However, I ran into an issue where a machine that dual boots into 2 different Windows OS generates different site codes on each OS, which should ideally not happen.

但是,我遇到了一个问题,即双启动到 2 个不同 Windows 操作系统的机器在每个操作系统上生成不同的站点代码,理想情况下应该不会发生这种情况。

For reference, these are the metrics I'm currently using:

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

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

采纳答案by Jonas Gulle

Parse the SMBIOSyourself and hash it to an arbitrary length. See the PDF specificationfor all SMBIOS structures available.

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

To query the SMBIOS info from Windows you could use EnumSystemFirmwareEntries, EnumSystemFirmwareTablesand GetSystemFirmwareTable.

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

IIRC, the "unique id" from the CPUID instruction is deprecated from P3 and newer.

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

回答by Fabio Ceconello

I had the same problem and after a little research I decided the best would be to read MachineGuidin registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography, as @Agnus suggested. It is generated during OS installation and won't change unless you make another fresh OS install. Depending on the OS version it may contain the network adapter MAC address embedded (plus some other numbers, including random), or a pseudorandom number, the later for newer OS versions (after XP SP2, I believe, but not sure). If it's a pseudorandom theoretically it can be forged - if two machines have the same initial state, including real time clock. In practice, this will be rare, but be aware if you expect it to be a base for security that can be attacked by hardcore hackers.

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

Of course a registry entry can also be easily changed by anyone to forge a machine GUID, but what I found is that this would disrupt normal operation of so many components of Windows that in most cases no regular user would do it (again, watch out for hardcore hackers).

当然,任何人也可以轻松更改注册表项以伪造机器 GUID,但我发现这会破坏 Windows 的许多组件的正常运行,而在大多数情况下,普通用户不会这样做(再次,请注意对于铁杆黑客)。

回答by Paul Alexander

With our licensing toolwe consider the following components

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

  • MAC Address
  • CPU (Not the serial number, but the actual CPU profile like stepping and model)
  • System Drive Serial Number (Not Volume Label)
  • Memory
  • CD-ROM model & vendor
  • Video Card model & vendor
  • IDE Controller
  • SCSI Controller
  • MAC地址
  • CPU(不是序列号,而是实际的 CPU 配置文件,如步进和型号)
  • 系统驱动器序列号(非卷标)
  • 记忆
  • CD-ROM 型号和供应商
  • 显卡型号和供应商
  • IDE控制器
  • SCSI 控制器

However, rather than just hashing the components and creating a pass/fail system, we create a comparable fingerprintthat can be used to determine how different two machine profiles are. If the difference rating is above a specified tolerance then ask the user to activate again.

然而,我们不只是散列组件并创建通过/失败系统,而是创建了一个可比较的指纹,可用于确定两台机器配置文件的不同之处。如果差值高于指定的容差,则要求用户再次激活。

We've found over the last 8 years in use with hundreds of thousands of end-user installs that this combination works well to provide a reliably unique machine id - even for virtual machines and cloned OS installs.

我们在过去 8 年中发现,在数十万最终用户安装的使用中,这种组合可以很好地提供可靠的唯一机器 ID - 即使对于虚拟机和克隆操作系统安装也是如此。

回答by gizmo

What about just using the UniqueID of the processor?

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

回答by Jonathan Adelson

I hate to be the guy who says, "you're just doing it wrong" (I always hate that guy ;) but...

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

Does it have to be repeatably generated for the unique machine? Could you just assign the identifier or do a public/private key? Maybe if you could generate and store the value, you could access it from both OS installs on the same disk?

是否必须为唯一的机器重复生成?你可以只分配标识符或做一个公钥/私钥吗?也许如果您可以生成并存储该值,您就可以从安装在同一磁盘上的两个操作系统访问它?

You've probably explored these options and they doesn't work for you, but if not, it's something to consider.

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

If it's not a matter of user trust, you could just use MAC addresses.

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

回答by Kyle Cronin

You should look into using the MAC address on the network card (if it exists). Those are usually unique but can be fabricated. I've used software that generates its license file based on your network adapter MAC address, so it's considered a fairly reliable way to distinguish between computers.

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

回答by AngelBlaZe

In my program I first check for Terminal Server and use the WTSClientHardwareId. Else the MAC address of the local PC should be adequate.

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

If you really want to use the list of properties you provided leave out things like Nameand DriverVersion, Clockspeed, etc. since it's possibly OS dependent. Try outputting the same info on both operating systems and leave out that which differs between.

如果你真的想使用属性的列表中,您提供的离开了之类的东西NameDriverVersionClockspeed等等。因为它可能与操作系统有关。尝试在两个操作系统上输出相同的信息,并忽略不同的信息。

回答by cmcginty

For one of my applications, I either use the computer name if it is non-domain computer, or the domain machine account SID for domain computers. Mark Russinovich talks about it in this blog post, Machine SID:

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

The final case where SID duplication would be an issue is if a distributed application used machine SIDs to uniquely identify computers. No Microsoft software does so and using the machine SID in that way doesn't work just for the fact that all DC's have the same machine SID. Software that relies on unique computer identities either uses computer names or computer Domain SIDs (the SID of the computer accounts in the Domain).

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

You can access the domain machine account SID via LDAP or System.DirectoryServices.

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

回答by ariwez

There is a library available for getting hardware specific informations: Hardware serial number extractor (CPU, RAM, HDD, BIOS)

有一个可用于获取硬件特定信息的库:硬件序列号提取器(CPU、RAM、HDD、BIOS)

回答by user2515235

I had an additional constraint, I was using .net express so I couldn't use the standard hardware query mechanism. So I decided to use power shell to do the query. The full code looks like this:

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