【问题标题】:Reliable way of generating unique hardware ID生成唯一硬件 ID 的可靠方法
【发布时间】:2011-02-19 23:46:39
【问题描述】:

问题:我必须为每个联网客户端提供唯一 ID,这样:

  • 一旦客户端软件安装在目标计算机上,它 (ID) 应该会持续存在,并且如果软件重新安装在同一台计算机和相同的操作系统安装上,它应该会持续存在,
  • 如果硬件配置以大多数方式修改(除了更换主板),它应该不会改变
  • 当安装了客户端软件的硬盘被克隆到具有相同硬件配置(或尽可能相似)的另一台计算机上时,客户端软件应该知道这种变化。

一点解释和一些背景故事:

这个问题基本上是一个古老的问题,也涉及软件复制保护的主题,因为这里提到了该领域使用的一些机制。在这一点上我应该清楚,我不是在寻找复制保护方案。请继续阅读。 :)

我正在开发一个应该在本地网络中运行的客户端-服务器软件。我必须解决的问题之一是识别网络中的每个唯一客户端(问题不大),以便我可以将某些属性应用于每个特定客户端,在特定的部署生命周期内保留和强制执行这些属性客户。

在寻找解决方案时,我意识到以下几点:

  • Windows 激活系统使用某种对硬件修改极为敏感的重指纹机制,
  • 磁盘映像软件沿所有卷 ID(格式化时绑定到每个分区)以及在安装过程中、首次运行期间或以任何其他方式生成的自定义唯一 ID 进行复制,这在本质上是严格的软件,并存储在注册表或硬盘上,所以很容易混淆两者。

此类问题的明显选择是找出 BIOS 标识符(虽然不能 100% 确定这是否在相同的主板型号中是唯一的),因为这是我唯一可以依赖的不重复的东西,通过克隆传输,并且无法更改(至少不能通过使用某些用户空间程序)。其他一切都失败了,要么不可靠(MAC 克隆,有​​人吗?),要么要求太高(因为它对配置更改过于敏感)。

我想问的子问题是,我在架构方面做得对吗?也许有更好的工具来完成我必须完成的任务......

我想到的另一种方法类似于握手机制,其中服务器维护连接的客户端 ID 的内部查找表(在任何给定时刻,它甚至可以完全基于软件且不唯一),并告诉如果在连接时提供了重复的 ID,则客户端在握手期间提供不同的 ID。不幸的是,这种方法不能很好地满足在生命周期内将属性绑定到特定客户端的要求之一。

【问题讨论】:

  • 嗨先生,一个有趣的问题,我做了一些研究,因为它引起了我的兴趣。但是我想到了一些事情,从不同的角度来看,您是否正在寻找一种在连接到服务器后唯一识别用户的方法?如果它可以在用户级别,而不是机器级别 - 您可以自己在服务器端生成 ID 并存储在机器上吗?类似于 session id 如何在 Web 应用程序中跟踪用户并存储 cookie(但将其保留更长时间)?

标签: windows client-server uniqueidentifier bios hardware-id


【解决方案1】:

您正在寻找的是Windows WMI。您可以获得主板 ID(在同一类型的主板上是唯一的)或许多其他类型的唯一标识符,并想出一些巧妙的种子函数来生成 UHID。哇,我只是编了一个首字母缩写词?

如果您正在寻找专门获取主板 (BIOS) ID:

WMI class: Win32_BIOS
Namespace: \Root\Cimv2

文档:http://msdn.microsoft.com/en-us/library/aa394077(VS.85).aspx
示例代码:http://msdn.microsoft.com/en-us/library/aa390423%28VS.85%29.aspx

编辑:您没有指定语言(我假设是 C++),但这可以在 Java(使用 COM 驱动程序)和任何 .NET 语言中完成。

【讨论】:

  • 正确,我没有指定语言,因为我发现特定语言与手头的问题无关。我对实现这一目标的更高层次的方法感兴趣。我觉得你的回答非常准确。我唯一需要知道的是这个接口是如何向后兼容的,即。使用这种方法支持多大的主板?
  • 我很确定自 90 年代初至中期以来所有 BIOS 都已标准化。 WMI 自 Windows 2000 以来就已经存在(并且可以作为 Windows 95 和 Windows NT 的补丁使用)。简而言之,您无需担心 :) 它完全向后兼容,除非您在 Windows 3.1 或 30 年前制造的计算机上安装软件。
  • 该死的,90 年代初到中期是 15 到 20 年前...谈论时间飞逝!我知道最近(比如 10 年前及以后)大多数制造商都将这些标准化,并且有兴趣了解它可以追溯到多少时间。现在我有我的答案了。谢谢。
  • 我返回了我的发现,关于对唯一的、与 BIOS 相关的标识符的支持。不幸的是,4-5 块主板(都是 1-2 年的)都没有 BIOS 序列号。难道我做错了什么?我使用提到的属性来生成唯一 ID,但无济于事......有什么想法吗?
  • 默认情况下,WMI 并非在所有计算机中都可用。此外,它很容易分解。我发生在我身上。幸运的是,有一个修复程序 (searchwindowsserver.techtarget.com/tip/Repairing-damaged-WMI)。无论如何,在这些情况下,许可证验证代码可能会失败。
【解决方案2】:

在我看来,您应该构造与您的要求相对应的唯一 ID。此 ID 可以根据对您很重要的信息(有关软件和硬件组件的一些信息)构建为 散列(如 MD5、SHA1 或 SHA512)。

如果您使用您的私钥签署此类哈希并且您的软件在启动期间验证密钥(签名的哈希值)已签名(只有公钥必须是与您的软件一起安装)。可以通过不同的在线服务扩展此类解决方案,但企业客户可能会发现在线服务不太好。

【讨论】:

  • 软件组件不可靠,因为它很容易被克隆,对吧?正如您所建议的,将两者结合起来可能是一个更好的解决方案,因为这可以使远程服务器能够识别克隆的客户端,从而调用它们。好主意。谢谢。
  • 我的意思是,您可以生成一个字符串或字节数组,其中包含所有重要且在计算机克隆过程中保持不变的信息(此信息的串联)。然后你从这个字节数组中计算一个哈希值。此哈希值将是您的唯一 ID。您在软件安装期间保存此类哈希值。每次启动软件时,您都会再计算一次 ID(哈希)并与安装期间保存的值进行比较。这不是你想要的吗?如何读取硬件信息不是问题。包含 WMI 的方法有很多。
  • 虽然这与我正在寻找的非常接近,但另一张海报提供了更中肯的答案。但是,我必须强调,我喜欢您的建议,即根据“有关软件和硬件组件的信息”构建哈希。这让我想到了我可能加入的附加功能,即通过具有单独的硬件和软件 ID 来检测克隆客户端的能力 - 假设硬件 ID 是真正唯一的,而软件 ID 可能不是唯一的,在这种情况下,它是明显克隆的实例。
  • 如果您不知道如何读取 BIOS 或 MAC 信息,您应该在问题中提出这个问题。此外,无论您使用 .NET 还是非托管代码、C/C++ 还是 VB 等,您都不会编写。对于 C/C++ 开发人员来说,使用 WMI 不是最简单也不是最好的方法,有很多简单的类似 C 的 Windows API 可以为您提供所需的信息。当您正在寻找构建像 Microsoft 和其他类似的 ID 的想法时,您的问题听起来更多。我只是简短地解释了这种实现的主要思想。祝你好运。
  • 谢谢,我可能描述性太强了,无法解释我想要完成的任务。我并不是说我在寻找确切的代码解决方案,而是我在寻找一条唯一可识别的信息,例如 BIOS 和/或主板 ID 字符串。我将如何阅读它是另一个故事(尽管我已经获得了可以从中阅读它的精确位置)。诚然,正如您所建议的那样,WMI 可能不是要走的路。很抱歉造成混乱。老实说,我一直在寻找关于这个主题的第二个意见,这正是我从你们两个那里得到的。非常感谢!
【解决方案3】:

许多程序使用 hostId 来构建许可证代码(例如基于 FlexLM 的程序)。看看 Matlab 根据操作系统做了什么:

http://www.mathworks.com/support/solutions/en/data/1-171PI/index.html

也看看这个问题:

Getting a unique id from a unix-like system

我还看到一些程序的许可证基于硬盘驱动器的序列号,这可能是不太可能改变的事情。有些人会建议使用以太网卡的 MAC,但可以重新编程。

【讨论】:

  • 这个项目的好处是用户不必费力改变MAC,因为这样做他们将一无所获(因为它不是软件保护的形式)。但是,由于程序的性质,硬盘序列号不是一个选项,不幸的是:( MAC 很麻烦,因为当 NIC 被禁用时,即使联网的计算机也不会暴露它们的 MAC 地址...... :( 这让我很可能大多数用户不会弄乱他们的 NIC(因为他们不应该,因为这个程序与网络密切相关)。
【解决方案4】:

MAC
不要依赖 MAC!曾经。它不是永久性的。用户可以轻松更改它 (under 30 seconds)。

卷 ID
不要依赖卷 ID!曾经。它不是永久性的。用户可以很容易地改变它。它也可以通过简单地格式化驱动器来改变。

WMI
WMI 是一项服务。可以很容易地禁用。实际上,我试过了,我发现在许多计算机上都被禁用或损坏(是的,经常损坏)。

许可证服务器
连接到验证服务器也可能会给您带来很多麻烦,因为:
* 您的客户可能并不总是连接到互联网。
* 您的客户可能会使用特殊设置(路由器/NAT/代理/网关)进行连接,他们需要将这些设置输入到您的程序中才能连接到验证服务器。
*它们可能位于防火墙后面,该防火墙将阻止除少数(我的情况)之外的所有程序。在某些情况下,防火墙可能不受他们的控制(对大多数企业用户有效)!
* super easy 将您的程序重定向到模拟您的许可服务器的本地虚假网络服务器。

硬件数据
如果您需要强大的保护,您需要依赖硬件。用户无法编辑的内容。类似于 Intel/AMD CPU 中可用的 CPU ID 指令以及写入驱动器 IDE 接口的序列号。
CPU ID 和 HDD ID 是永久的。它们永远不会改变,即使在您格式化计算机并重新安装 Windows 之后也是如此。

这是可行的。例如this library 读取计算机的硬件 ID。有一个编译的演示,还有源代码/DLL。免责声明:该链接指向商业产品(19 欧元/无版税)。

【讨论】:

  • 很抱歉,但这并不能回答问题 - 它只是链接到一个带有“解决问题”的假定 DLL 的商业网站。
  • @robnick - 它还显示了哪些选项保证不起作用:)
  • @robnick ...我没有强迫任何人从他们的口袋里“掏”钱来购买那个 DLL。我只是建议可以这样做,因为其他人已经这样做了。问这个问题的人可以实现他自己的 ASM 代码来从 IDE 驱动接口板获取 ID。但是,如果他要开始深入研究高级硬件文档来编写自己的 ASM 代码,那么为了节省 19 欧元,他必须非常便宜 :)
  • 我可以发誓我回复了你最近的评论。看,您正在回复 4 年前的评论。在更新您的答案以使其清晰方面做得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
相关资源
最近更新 更多