生成唯一的机器 ID
我需要编写一个函数来生成一个对于运行 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
I need to write a function that generates an id that is unique for a given machine running a Windows OS.
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.
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.
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
从 Windows 10 1607(“周年更新”Build 14393)开始,系统可以通过
Windows.System.Profile.SystemIdentification
类。GetSystemIdForPublisher()
返回一个设备 ID,即此 API 使用 TPM 或 UEFI。 如果两者都不存在,系统会生成一个新 ID 并将其保留在注册表中。 在此情况下,上述保证不成立。 API 将通过
来源
属性。以下 C++ 代码请求设备 ID 并将十六进制编码表示与其源一起打印到 STDOUT:
此标准“Windows 控制台应用程序 (C++/WinRT)”具有以下 packages.config 文件:
Raymond Chen 的博客文章 如何获得 Windows 系统的签名,即使该签名也将保持不变如果用户重新安装 Windows? 还有一些文档中未详细说明的详细信息。
Starting with Windows 10 1607 ("Anniversary Update" Build 14393), the system can generate a unique device ID via the
Windows.System.Profile.SystemIdentification
class.GetSystemIdForPublisher()
returns a device ID, thatThis API uses the TPM or UEFI. If neither is present, the system generates a new ID and persists it in the registry. In that case, the above guarantees do not hold. The API will report how reliable the ID is through the
Source
property.The following C++ code requests the device ID and prints a hex-encoded representation to STDOUT alongside its source:
This standard "Windows Console Application (C++/WinRT)" has the following packages.config file:
Raymond Chen's blog post How can I get a signature for a Windows system that will remain unchanged even if the user reinstalls Windows? has a few more details that aren't spelled out in the documentation.
也许有点作弊,但现在机器以太网适配器的 MAC 地址很少在主板不改变的情况下改变。
Maybe cheating a little, but the MAC Address of a machines Ethernet adapter rarely changes without the motherboard changing these days.
我讨厌成为那个说“你只是做错了”的人(我总是讨厌那个人;)但是......
它是否必须为独特的机器重复生成? 您可以只分配标识符或执行公钥/私钥吗? 也许如果您可以生成并存储该值,您就可以从同一磁盘上安装的两个操作系统访问它?
您可能已经探索过这些选项,但它们并不适合您,但如果不适合,则需要考虑。
如果不是用户信任问题,您可以只使用 MAC 地址。
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.
您可以获取某种制造商序列号或服务标签吗?
我们的商店是戴尔商店,因此我们使用每台机器唯一的服务标签来识别它们。 我知道它可以从 BIOS 中查询,至少在 Linux 中,但我不知道如何在 Windows 中执行此操作。
Can you pull some kind of manufacturer serial number or service tag?
Our shop is a Dell shop, so we use the service tag which is unique to each machine to identify them. I know it can be queried from the BIOS, at least in Linux, but I don't know offhand how to do it in Windows.
我有一个额外的限制,我使用的是 .net express,所以我无法使用标准硬件查询机制。 所以我决定使用power shell来进行查询。 完整的代码如下所示:
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:
查找 CPUID 以获得一个选项。 多 CPU 系统可能会出现一些问题。
Look up CPUID for one option. There might be some issues with multi-CPU systems.
在我的程序中,我首先检查终端服务器并使用 WTSClientHardwareId。 否则本地 PC 的 MAC 地址应该足够了。
如果您确实想使用您提供的属性列表,请忽略
Name
和DriverVersion
、Clockspeed
等,因为它可能取决于操作系统。 尝试在两个操作系统上输出相同的信息,并忽略不同的信息。In my program I first check for Terminal Server and use the WTSClientHardwareId. Else the MAC address of the local PC should be adequate.
If you really want to use the list of properties you provided leave out things like
Name
andDriverVersion
,Clockspeed
, etc. since it's possibly OS dependent. Try outputting the same info on both operating systems and leave out that which differs between.对于我的一个应用程序,如果是非域计算机,则使用计算机名称;如果是域计算机,则使用域计算机帐户 SID。 Mark Russinovich 在这篇博文中讨论了这个问题,机器 SID< /a>:
您可以通过 LDAP 或 System.DirectoryServices 访问域计算机帐户 SID。
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:
You can access the domain machine account SID via LDAP or
System.DirectoryServices
.只使用处理器的 UniqueID 怎么样?
What about just using the UniqueID of the processor?
您应该考虑使用网卡上的 MAC 地址(如果存在)。 这些通常是独特的,但可以伪造。 我使用过根据网络适配器 MAC 地址生成许可证文件的软件,因此它被认为是区分计算机的相当可靠的方法。
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.
自己解析 SMBIOS 并将其哈希为任意长度。 有关所有可用的 SMBIOS 结构,请参阅 PDF 规范。
要从 Windows 查询 SMBIOS 信息,您可以使用
EnumSystemFirmwareEntries
,EnumSystemFirmwareTables
和GetSystemFirmwareTable
。IIRC,CPUID 指令中的“唯一 ID”从 P3 及更高版本中已弃用。
Parse the SMBIOS yourself and hash it to an arbitrary length. See the PDF specification for all SMBIOS structures available.
To query the SMBIOS info from Windows you could use
EnumSystemFirmwareEntries
,EnumSystemFirmwareTables
andGetSystemFirmwareTable
.IIRC, the "unique id" from the CPUID instruction is deprecated from P3 and newer.
通过我们的许可工具,我们考虑以下组件
但是,我们不只是对组件进行散列并创建通过/失败系统,而是创建一个 可比较的指纹,可用于确定两台计算机配置文件的差异程度。 如果差异等级高于指定的容差,则要求用户再次激活。
我们在过去 8 年的数十万最终用户安装使用中发现,这种组合可以很好地提供可靠的唯一机器 ID - 即使对于虚拟机和克隆操作系统安装也是如此。
With our licensing tool we consider the following components
However, rather than just hashing the components and creating a pass/fail system, we create a comparable fingerprint that 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.
我遇到了同样的问题,经过一番研究后,我决定最好的办法是读取注册表项
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
中的MachineGuid
,正如 @Agnus 所建议的那样。 它是在操作系统安装期间生成的,除非您重新安装另一个操作系统,否则不会更改。 根据操作系统版本,它可能包含嵌入的网络适配器 MAC 地址(加上一些其他数字,包括随机数)或伪随机数,后者适用于较新的操作系统版本(我相信在 XP SP2 之后,但不确定)。 如果它是伪随机的,理论上它可以被伪造 - 如果两台机器具有相同的初始状态,包括实时时钟。 实际上,这种情况很少见,但如果您希望它成为可能受到铁杆黑客攻击的安全基础,请注意。当然,任何人都可以轻松地更改注册表项来伪造机器 GUID,但我发现这会破坏 Windows 的许多组件的正常运行,在大多数情况下,普通用户不会这样做(再次提醒,请注意)对于铁杆黑客来说)。
I had the same problem and after a little research I decided the best would be to read
MachineGuid
in registry keyHKEY_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.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).