生成基于硬件的计算机ID

问题描述 投票:6回答:6

我有一个关于出于许可目的生成特定计算机ID的问题。优选地,该ID应该基于硬件,并且因此例如在用户重新格式化时不应改变。对于用户来说,改变生成ID所依据的信息也不容易(或者优选甚至是不可能的)。目前,我只有两个组成部分,即CPUID标准和功能标志以及计算机中第一个物理驱动器的几何形状和总大小。虽然这似乎对大多数普通PC来说都是不错的选择,但例如许多上网本都是使用完全相同的硬件制造的,因此在这种情况下,您将为许多计算机获得相同的ID。谁能建议我可以使用其他硬件组件?

我有两个要求:

  1. 不得使用WMI。

  2. 它必须在很多情况下都可以使用(包括没有特权或特权很少的用户)。我曾考虑过使用物理驱动器的序列号,但是如果用户不在管理员模式下,这似乎很难找回。

我正在Windows上使用C ++。

谢谢您的任何建议。

c++ windows hardware unique
6个回答
4
投票

您可以使用第一个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 );
}

恕我直言,这足以获得价值一千美元的许可软件,其中所需要的只是防止临时消费者与邻居共享您的软件。有动机的海盗可以绕开它,但是拥有足够知识和动力的海盗却不足以使您值得花更多的精力去击败他们,更重要的是,您不希望给诚实的客户带来不便。

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

我也不相信会堆积更多的硬件签名,磁盘驱动器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 )
    {
        // check for ethernet card, ignoring software loopbacks and other strange things that might be present
        if( pinfo->Type == MIB_IF_TYPE_ETHERNET )
        {
            continue;
            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;
    }

}

3
投票

几年前,我尝试做类似的事情,但失败了。我尝试使用可以读取的硬件ID的组合。大多数CPU都有一个CPUID,这是一个唯一编号,用于唯一地标识和跟踪它们。但是,问题在于,它不建议每个CPU都具有此ID。实际上,当我尝试使用Intel Celeron系列产品时没有此ID。某些主板(主要是Intel)还附带了可以使用的唯一ID。

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

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

还要记住,虚拟机使这一点更加复杂。我认为您最好的选择是做Microsoft要做的事情。

Microsoft确实使用类似的方法,即获取安装了操作系统的计算机的硬件指纹,并将其与注册密钥进行通信以激活OS / Office套件的副本。如果您大幅升级硬件(我认为是4个硬件组件),则密钥将更改,您将必须与Microsoft联系并提供证明以重新验证Windows副本。


2
投票

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

如果每台计算机必须相同并且生成多次,则MAC地址是计算机的通用ID(尽管您可以选择多个MAC。)>


1
投票

如果这样的事情简单可靠,Microsoft早就可以找到它并申请了专利。


0
投票

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


© www.soinside.com 2019 - 2024. All rights reserved.