我考虑使用Matlab Compiler以价格分发软件。我正在研究(非常)简单的方法来阻止重新分发,而不会让用户烦恼。有什么建议吗?
一种想法是通过电子邮件向用户发送许可证密钥,并在安装过程中将其输入以在许可证服务器上进行验证。如果密钥与服务器上的密钥匹配,则安装将照常进行,否则会显示警告消息以通知用户购买另一个许可证。但是,此方法需要指定的功能仅在安装过程中运行,而不是此后(以免使用户烦恼)。这可能是使用Matlab编译器或其他方式吗?
我想我可以在用户磁盘上创建一个文件,程序在启动时会查找该文件(如果它存在,那么它第一次没有运行),但是如果用户复制了整个文件目录,该文件也会被复制。
答案 0 :(得分:1)
为了创建有效的许可系统,您必须将其链接到用户计算机的一个或多个属性(MAC地址,操作系统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下运行的计算机上可用的标识符。
如果要使许可系统适应所有可能的操作系统和环境,则必须使用更通用的方法,基于通用的硬件属性: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的评论中找到了它。