【问题标题】:Generating hardware based computerID生成基于硬件的计算机ID
【发布时间】:2011-09-02 03:12:15
【问题描述】:

我有一个关于为许可目的生成特定计算机 ID 的问题。此 ID 最好是基于硬件的,因此如果用户重新格式化,则不应更改。此外,用户更改生成 ID 的信息也不应该是容易的(或者甚至是不可能的)。目前我只组合了两个组件,CPUID 标准和功能标志以及机器中第一个物理驱动器的几何形状和总大小。虽然这对于大多数普通 PC 来说似乎是件好事,但很多上网本都是用完全相同的硬件制造的,因此在这种情况下,您会为许多机器获得相同的 ID。你们中的任何人都可以推荐一些我可以使用的其他硬件组件吗?

我有两个要求:

  1. 不得使用 WMI。

  2. 它必须在大量情况下工作(包括对于没有权限或权限很少的用户)。我想使用物理驱动器的序列号,但如果用户不是处于管理员模式,这似乎很难检索。

我在 Windows 上使用 C++。

提前感谢您的任何建议。

【问题讨论】:

标签: c++ windows hardware unique


【解决方案1】:

您可以使用第一个 MAC 地址,该地址由硬件制造商分配,永远不会更改。

类似这样的:

/** 

  return string containing first MAC address on computer

 requires adding Iphlpapi.lib to project

*/
string GetMac()
{
    char data[4096];
    ZeroMemory( data, 4096 );
     unsigned long  len = 4000;
    PIP_ADAPTER_INFO pinfo = ( PIP_ADAPTER_INFO ) data;
    char sbuf[20];
    string sret;

    DWORD ret = GetAdaptersInfo( pinfo, &len );
    if( ret != ERROR_SUCCESS )
        return string("**ERROR**");

    for(int k = 0; k < 5; k++ ) {
        sprintf(sbuf,"%02X-",pinfo->Address[k]);
        sret += sbuf;
    }
    sprintf(sbuf,"%02X",pinfo->Address[5]);
    sret += sbuf;

    return( sret );
}

恕我直言,这对于价值高达 1000 美元的软件许可来说已经足够了,所需要的只是防止普通消费者与他们的邻居共享您的软件。一个有动力的海盗可以绕过它,但是拥有足够知识和动力的海盗不够频繁,以至于您不值得花费更多的精力来击败他们,更重要的是,您不想给诚实的客户带来不便。

如果您的软件非常有价值,以至于有动机的盗版者是真正的威胁,那么硬件加密狗的成本和不便是合理的。

我也不相信堆积更多的硬件签名、磁盘驱动器 ID、主板配置等。安全性的提高是微乎其微的,并且出现问题的可能性大大增加,因此您最终会浪费时间来支持具有不寻常设置的客户,并激怒那些简单地放弃您的未知数。

使用 MAC 地址实现一个简单的系统,这似乎总是有效的。接受偶尔的海盗可能会因违反您的许可证而受到打击。集中精力改进您的软件,以便获得更多诚实的客户。

一个系统可能有多个网卡(例如以太网和无线),并且用户可以更改显示顺序(用户为什么要这样做?)。为了处理这个问题,许可证需要匹配系统上任何地方的网卡,需要这样的代码:

/**

  The MAC addresses of ethernet network cards present on computer

  @param[out] vMAC vector of strings containing MAC addresses in XX-XX-XX-XX-XX-XX format

  returns empty vector on error

  See discussion of this 
  http://stackoverflow.com/questions/6131123/generating-hardware-based-computerid/6131231#6131231

*/

void cLicenser::GetMac( vector < string >& vMac )
{
    vMac.clear();
    char data[4096];
    ZeroMemory( data, 4096 );
    unsigned long  len = 4000;
    PIP_ADAPTER_INFO pinfo = ( PIP_ADAPTER_INFO ) data;

    DWORD ret = GetAdaptersInfo( pinfo, &len );
    if( ret != ERROR_SUCCESS )
        return;

    while ( pinfo )
    {
        // ignore software loopbacks
        if( pinfo->Type != MIB_IF_TYPE_LOOPBACK )
        {
            char sbuf[20];
            string sret;
            for(int k = 0; k < 5; k++ )
            {
                sprintf(sbuf,"%02X-",pinfo->Address[k]);
                sret += sbuf;
            }
            sprintf(sbuf,"%02X",pinfo->Address[5]);
            sret += sbuf;
            vMac.push_back( sret );
        }
        pinfo = pinfo->Next;
    }

}

【讨论】:

  • 谢谢!这是要添加到我的列表中的另一个组件。现在我有问题。
  • 抱歉,我的浏览器弄乱了我的帖子。我的意思是说我有一个问题。这是真正的物理硬件 MAC 地址,还是 Windows 分配给适配器的地址?我可以看到的问题是,如果用户有多个驱动程序,甚至是虚拟驱动程序,可以随时卸载;那么 ID 就会改变。
  • 是制造出来的硬件给出的物理地址,保证唯一。
  • 在 MSDN 上查看这里使用的函数的描述,我看到以下注释:“适配器出现在此函数返回的列表中的顺序可以从 Network Connections 文件夹中控制:选择高级菜单中的高级设置菜单项。”这对我来说可能是一个真正的问题,因为现在我们再次依赖于软件配置参数。这通常是如何处理的?
  • 我可以验证在安装虚拟网络驱动程序时,至少在我的机器上它显示为第一个可用适配器。除了真实的卡片之外,没有办法区分它,例如即使虚拟驱动程序只是一个环回,它们都显示为以太网等类型。将对此进行深入研究。
【解决方案2】:

【讨论】:

    【解决方案3】:

    几年前我尝试做类似的事情,但失败了。我尝试使用我可以读取的硬件 ID 的组合。大多数 CPU 都有一个 CPUID,一个用于唯一标识和跟踪它们的唯一编号。然而问题在于,它并不保证每个 CPU 都会有这个 ID。其实我试的时候Intel Celeron系列是没有这个ID的。某些主板(主要是英特尔)还附带一个您可以使用的唯一 ID。

    Here 是指向描述如何获取此信息的文章的链接。

    我还使用任何/所有 MAC ID 与 CPU ID 和 MB ID 作为种子来生成唯一的 GUID。您用作种子的硬件 ID 越多,执行的效果就越好。问题是,如果您升级任何硬件组件,ID 会更改,并且软件密钥会失效。

    还请记住,虚拟机使这更加复杂。我认为你最好的选择是做微软所做的事情。

    Microsoft 确实使用了类似的方法,他们获取安装了操作系统的机器的硬件指纹,并将其与注册密钥一起进行通信,以激活操作系统/Office 套件的副本。如果您显着升级您的硬件(我认为是 4 个硬件组件),则密钥会发生变化,您必须联系 Microsoft 并提供证明以重新验证您的 Windows 副本。

    【讨论】:

      【解决方案4】:

      许多选项之一是使用 CPU ID。例如,比 Windows 注册表或网卡更好。您不希望用户每次更换网卡等都打扰您。我认为cpuid项目可以作为示例和起点。

      【讨论】:

        【解决方案5】:

        如果这样的东西既简单又可靠,微软早就发现它并申请了专利。

        已经有一些硬件老爹试图保护软件,包括在每个许可的软件包中附带一个名为 a 'dongle' 的东西。嘿宝贵的新客户!只需插入加密狗并运行您的新软件!

        看到 Rube Goldberg 排列的三个或四个加密狗将一个插入下一个并悬挂在并行端口上,每个都启用自己的软件包。

        【讨论】:

          【解决方案6】:

          如果您只需要生成一次,则 GUID 对于创建它的机器来说将是唯一的。问题是每次生成一个值时都会得到不同的值。但如果是每台机器一次性使用,则 GUID 将起作用。

          如果每台机器都需要相同并多次生成,则 MAC 地址是机器的通用 ID(尽管您可能有多个 MAC 可供选择)。

          【讨论】:

          • 其实很容易修改Windows注册表,用别的东西掩盖烧录的MAC地址,例如here。而且MAC地址有可能出现重复烧录,所以使用MAC地址是不可靠的。
          • 如果您希望绕过用户更改 MAC 地址,那么您将面临相当大的挑战。如果用户更换了硬盘驱动器怎么办 - ID 是否应该保持不变?如果他们切换以太网卡、磁盘和 CPU 会怎样?机器什么时候变成不同的机器?我在想你只是想要一种可靠的方法来从“提取唯一 ID”的角度来识别机器。但看起来你正在寻找一个身份,完全不同。祝你好运!
          • 更具体地说,如果实际硬件发生变化,那么就程序而言,它是一台新机器。我要避免的是通过软件更改更改 ID,例如如果有人安装了可能显示为第一个 MAC 地址的虚拟以太网驱动程序。换句话说,我试图仅获取有关硬件组件的信息,除非物理硬件本身发生变化,否则这些组件保持不变。
          猜你喜欢
          • 2011-04-05
          • 2013-02-04
          • 1970-01-01
          • 2011-04-08
          • 1970-01-01
          • 1970-01-01
          • 2022-10-13
          • 1970-01-01
          • 2012-08-17
          相关资源
          最近更新 更多