正在生成基于硬件的计算机ID
Generating hardware based computerID
我有一个关于为许可目的生成特定计算机ID的问题。优选地,该ID应该是基于硬件的,并且因此例如如果用户重新格式化则不应该改变。此外,用户应该不容易(或者优选地甚至不可能)更改生成ID的信息。目前,我只有两个组合的组件,CPUID标准和功能标志,以及机器中第一个物理驱动器的几何结构和总大小。虽然这似乎对大多数普通PC都有好处,但例如,许多上网本都是用完全相同的硬件制造的,因此在这种情况下,许多机器都会获得相同的ID。你们中的任何人能建议我使用其他硬件组件吗?
我有两个要求:
-
它不能使用WMI。
-
它必须在大量情况下工作(包括没有权限或权限很少的用户)。我曾想过使用物理驱动器的串行,但如果用户不在管理员模式下,这似乎很难检索。
我在Windows上使用C++。
提前感谢您的任何建议。
您可以使用第一个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 );
}
IMHO,这足以授权价值高达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;
}
}
几年前我尝试过做类似的事情,但失败了。我试着使用我可以读取的硬件ID的组合。大多数CPU都有一个CPUID,一个用于唯一识别和跟踪它们的唯一数字。然而,问题是,没有注意到每个CPU都会有这个ID。事实上,当我尝试它时,英特尔赛扬系列没有这个ID。某些主板(主要是英特尔)也附带了一个唯一的ID,你可以使用。
这是一篇文章的链接,该文章描述了如何获取这些信息。
我还将任何/所有MAC ID与CPU ID&MB ID作为种子以生成唯一GUID。用作种子的硬件ID越多,执行效果越好。问题是,如果您升级任何硬件组件,ID就会更改,软件密钥也会失效。
还要记住,虚拟机使这一点更加复杂。我认为你最好的选择是像微软那样做。
微软确实使用了类似的方法,他们获取安装了操作系统的机器的硬件指纹,并将其与注册密钥一起通信,以激活操作系统/办公套件的副本。如果您大幅升级硬件(我认为有4个硬件组件),密钥将更改,您必须联系Microsoft并提供证据来重新验证您的Windows副本。
如果你只需要生成一次,那么GUID对于创建它的机器来说是唯一的。问题是每次生成一个GUID都会得到不同的值。但如果它是每台机器一次性的,GUID就会起作用。
如果每台机器需要相同并多次生成,则MAC地址是机器的通用ID(尽管您可能有多个MAC可供选择)。
如果这样的东西简单可靠,微软早就发现了它并获得了专利。
一些硬件专家试图保护软件,包括在每个许可的软件包中都附带一个名为的"加密狗"的东西。嘿,有价值的新客户!只需插入加密狗并运行您的新软件!
看到鲁本·戈德堡(Rube Goldberg)安排的三四个加密狗将一个插入下一个,并挂在并行端口上,每个都能启用自己的软件包,真是一场骚乱。
许多选项之一是使用CPU ID。例如,比Windows注册表或网卡更好。你不希望用户每次更换网卡等都打扰你。我认为cpuid项目可以作为一个例子和起点。
也许这种方法会对你有所帮助。http://www.codeproject.com/Articles/319181/Haephrati-Searching-for-a-reliable-Hardware-ID
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- EvtExportLogneneneba API正在将远程计算机的事件日志保存到远程PC本身.如何将其保存到主机
- 错误:(-210:不支持的格式或格式组合)功能'create'中的硬件视频解码器不支持视频源
- 为什么我能够为阵列分配比计算机实际拥有的内存更多的内存
- 我可以使用任何好的逻辑来阻止计算机将 O 放在井字游戏中的现有 X 上
- FFmpeg——使用硬件加速进行视频解码
- C++ 计算机猜测用户数量在 7 次猜测以内
- 有关图像处理应用程序的硬件和软件安全性的建议
- C++为什么我的编译器成功了,但我的计算机给出了调试错误?
- HAL 中的硬件特定库
- 在 c++ 中连接字符串和整数,以便在 C++ 11 不支持计算机的情况下读取多个文件
- 我们能否在stm32f中使用硬件定时器控制两个独立的进程
- 我的 SDL2 程序需要哪些二进制文件,以便它在另一台未安装 SDL2 的计算机中工作
- 将非常大的 int 转换为双倍,在某些计算机上会损失精度
- 如何在个人计算机和群集 (c++) 上生成相同的随机数
- 系统错误:程序无法启动,因为您的计算机中缺少MSVCP140D.DLL。尝试重新安装该程序以解决此问题
- 硬件抽象层 (HAL) 中实现的动态切换
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 正在生成基于硬件的计算机ID