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