我正在考虑使用Matlab编译器以一定的价格分发软件。我正在研究(非常)简单的方法来阻止重新分发而不会惹恼用户。有什么建议吗?
一种想法是通过电子邮件向用户发送许可证密钥,并让他们在安装过程中输入该密钥以在许可证服务器上进行验证。如果密钥与服务器上的密钥匹配,则安装将照常进行,否则,将显示警告消息,通知用户购买另一个许可证。但是,此方法要求指定的功能仅在安装过程中运行,而在此之后不再运行(以免使用户烦恼)。是否可以使用Matlab编译器或其他方式?
我想我可以在用户的磁盘上创建一个文件,程序在启动时会寻找该文件(如果存在,则表示它不是第一次运行),但是如果用户复制了整个目录,该文件将被复制太。
最佳答案
为了创建有效的许可系统,您必须将其链接到用户计算机的一个或多个属性(MAC地址,OS ID,硬盘序列号,CPU序列号等)。
如果您不这样做,您将要发布可以从一个用户转移到另一个用户的许可证。如果一个用户决定在全局范围内分发其许可证文件,那么您将注定要失败,因为每个人都可能会使用该许可证文件并将其用于解锁您的应用程序。
但是,如上所述,如果将许可证文件链接到用户计算机的一个或多个属性,则必须能够获得以下任一属性:
在用户决定购买您的应用程序之前
第一种情况
您以试用版形式发布软件。第一次启动时,您可以在注册表中或隐藏在某个位置的文件中设置到期日期。您可以在应用程序启动时检查到期日期,一旦到达到期日期,就会抛出错误,并且不再让使用过的应用程序玩游戏。
在应用程序中,您可以在某处创建一个
Register Now
按钮。单击时,应用程序将检索机器属性并将其传递到将打开的网页/表格,以允许用户执行付款。该页面将负责验证机器属性,接收付款并最后根据这些属性提供有效的许可证代码。在应用程序内,您必须实现允许表单创建许可证代码的逻辑,因为每次应用程序启动时,都需要使用它们来验证代码本身。伪代码示例:
mp1 = GetMachineProperty1();
mp2 = GetMachineProperty2();
mp3 = GetMachineProperty3();
lc = GetLicenseCode();
if (~strcmp(sha1([mp1 mp2 mp3]),lc))
errordlg('Invalid license code!');
return;
end
这是最简单的路径。但是请记住,如果用户计算机的一个或多个属性发生更改(因为他更改了设备或重新安装了操作系统),则他的许可证将失效,并且您将必须提供能够解决这种情况的客户支持服务。
第二场景
这个要难得多。您将无法事先知道用户的机器属性。因此,您的许可系统将分两步运行。当用户购买应用程序时,您将发布一个唯一的代码(例如,称为
LID
)。然后,一旦用户将其插入到您的应用程序中,您的应用程序必须将其与计算机属性一起发送回去。然后计算最终密钥(例如,称为LKey
)并将其发送回用户。mp1 = GetMachineProperty1();
mp2 = GetMachineProperty2();
mp3 = GetMachineProperty3();
lkey = GetLicenseKey();
if (~strcmp(sha1([mp1 mp2 mp3]),lkey))
errordlg('Invalid license code!');
return;
end
机器属性
通过注释为您提供了第一个解决方案:位于注册表项
MachineGuid
中的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
值。很好但它仅适用于Windows计算机。使用winqueryreg
访问注册表。另一个不错的选择是
Window Domain Controller Security ID
,它是另一个机器特定的唯一标识符。您可以在Matlab中使用Java
代码来检索它:wdc_sid = com.sun.security.auth.module.NTSystem.getDomainSID();
或通过Windows注册表项
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\GroupMembership
。如果要与旧的Matlab版本保持一定的向后兼容性,则应使用注册表方法。不幸的是,Window Domain Controller Security ID
是另一个标识符,仅在Windows下运行的计算机上可用。如果要使许可系统适应所有可能的OS和环境,则必须根据通用的硬件属性(MAC地址,硬盘序列等)使用更通用的方法。据我所知,最可靠的属性是MAC地址,因为它的唯一性(几乎没有被肯定)几乎是肯定的,而且更改网络适配器的频率非常低(实际上有更多机会破坏硬盘)。如下使用
Java
代码检索计算机网络适配器的MAC地址:mac_addrs = '';
net_int = java.net.NetworkInterface.getNetworkInterfaces();
while (net_int.hasMoreElements)
mac_addr = net_int.nextElement.getHardwareAddress();
if (~isempty(mac_addr))
mac_addrs = [mac_addrs, '-', sprintf('%.2X',typecast(mac_addr,'uint8'))];
end
end
mac_addrs = mac_addrs(2:end);
上面的计算将生成一个字符数组,该字符数组表示机器上找到的所有MAC地址的级联结果。同样,出于兼容性原因,这可能不适用于旧的Matlab版本,因此您必须使用一种更为复杂的方法,如here所述。
[编辑]
这种基于底层操作系统检索MAC地址的方法可能更容易:
switch computer('arch')
case {'maci','maci64'}
[~,a]=system('ifconfig');
c=strfind(a,'en0');if ~isempty(c),a=a(c:end);end
c=strfind(a,'en1');if ~isempty(c),a=a(1:c-1);end
% find the mac address
b=strfind(a,'ether');
mac_add=a(1,b(1)+6:b(1)+22);
case {'win32','win64'}
[~,a]=system('getmac');b=strfind(a,'=');
mac_add=a(b(end)+1:b(end)+19);
case {'glnx86','glnxa64'}
[~,a]=system('ifconfig');b=strfind(a,'Ether');
mac_add=a(1,b(1)+17:b(1)+33);
otherwise,mac_add=[];
end
我在this article的注释中找到了它。
关于matlab - Matlab编译器:在安装过程中保护软件的重新分发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47522507/