我正在开发一些桌面软件供客户转售.客户希望限制软件,以便注册码特定于一台且只有一台计算机.
除了使用网卡中的MAC之外,是否还有其他任何技术(适用于Windows和Mac OS X)以便唯一识别计算机?
另一种解决方案是使用加密狗的许可技术.这是一个小型设备,可插入主机上的USB或其他I/O端口,并作为激活软件的唯一物理密钥.
第三种解决方案是提供许可证管理器.也就是说,当软件启动时,它查询服务器在网络上(无论是在用户的局域网或者在您的公司通过互联网访问),用于验证客户的软件的使用是合法的.这是"并发许可证"的一个很好的解决方案,因此客户可以在许多主机上安装您的软件,但您可以在有限数量的主机上同时使用它. FLEXnet Publisher是许可证管理解决方案的示例.
网卡的MAC地址是我上次为一家许可软件在特定主机上运行的公司工作时使用的解决方案.
但是,我想提醒一下:如果你进行这种类型的许可,你必须预计它将成为一项持续的管理工作,以跟踪你的客户许可证.一旦你有几百个客户,你会惊讶于你有多少次接到电话请求更改密钥
"我们将服务器升级为千兆网络适配器,现在许可证无法运行,因为新适配器具有不同的MAC地址."
否则客户可能会更换整个机器,并需要更新的许可证才能在新机器上运行您的软件.几乎我每天都在我工作的公司接到这些电话.
如果您给他们一个新密钥,您还需要信任客户停止在旧计算机(或网络适配器)上使用您的软件.如果你不能相信他们首先遵守许可证,你怎么能相信他们会扔掉旧钥匙?
如果您不打算如何支持此管理活动,请不要以这种方式许可您的产品.您只会给那些本来会合作的好客户带来不便.
我会在这里扮演魔鬼的拥护者并告诉你这样的事情可能不是在"公共"中讨论的最好的事情.
话虽如此,看看其他人可能做了什么,并可能改进(或采取一部分)它.像你说的那样,MAC地址可能可以使用.我听说Windows和其他程序使用硬盘驱动器信息(序列号) - 根据这个站点,Windows激活检查10个不同的项目并使它们成为一个唯一的密钥.
最好的方法是在Windows中使用C#获取UUID
唯一识别Windows机器的最佳方法
public string GetUUID() { var procStartInfo = new ProcessStartInfo("cmd", "/c " + "wmic csproduct get UUID") { RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; var proc = new Process() { StartInfo = procStartInfo }; proc.Start(); return proc.StandardOutput.ReadToEnd().Replace("UUID", string.Empty).Trim().ToUpper(); }
我正在考虑的想法是使用一些与硬件相关的序列号或唯一ID,并将它们哈希在一起。
升级的内容:-内存-MAC(可以被欺骗,插入USB适配器等)
经常不升级的内容:-CPU -BIOS-主板
使用WMIC可能是获取某些信息的好方法,我将首先获取不经常更改的东西作为首选,我希望能够对至少2个序列号或设备进行指纹识别以用于生成注册密钥。
wmic cpu get DeviceId /format:value
这将获取CPU ID,您可以针对以下命令运行该命令:
1-CPU(cpu:DeviceID)2-主板(baseboard:serialnumber)3-BIOS(bios:serialnumber)
如果您没有至少获得2个填充值,请抓住
4-网络适配器-(nic:MACAddress)5-RAM-(memphysical:SerialNumber)
根据您的业务逻辑,您可以使用前两个序列号来创建您的注册号,并且如果您始终遵循相同的顺序,则在重新安装时,注册号仍然可以使用,但是如果设备发生更改或用户尝试在辅助计算机上安装ID更改使注册号无效。为了减少技术支持电话的数量,使用最少的硬件指纹识别将使您头疼的问题最少,并且如果您尝试使用最少的指纹进行升级,则可以进一步减轻麻烦。我的偏好是上面的顺序。
您可以使用Diffie-Hellman密钥交换方案,让用户使用其硬件ID作为有效负载生成私钥/公钥对,然后将此信息传递给注册服务器,注册服务器将使用公钥/私钥来进行注册。解密有效负载并计算注册密钥,以返回给最终用户。我喜欢使用JWT与JWT负载中包含的公共密钥来回传递消息。希望能有所帮助。
上面提到了UUID,这是一个好主意,您可以通过Windows cmd.exe使用以下命令来获得它:
wmic csproduct get UUID /format:value
免责声明这些命令仅适用于我认为2000及更高版本的Windows,但您需要进行验证,它们可能适用于2000以下的系统,但那时我确实尝试不支持这些设备。祝好运。
在Mac上:
system_profiler | grep "Serial Number (system)"
在Linux(debian)上:
sudo dmidecode -t system | grep "Serial Number"
dmidecode和system_profiler还有其他组件,可以从类似于Windows中的wmic的设备中获取序列号。我不在Mac上工作,因此无法确认确切的规格列表,但创建了一个LCD(最小公分母)列表,所有这三个命令可以访问的部件的序列号放在一起并整理到最小要升级或更改的零件。然后,由前2-3个数字组成的哈希值组合在一起就可以使唯一的机器ID更加可靠,甚至可以在更新了操作系统的设备上激活跨平台应用程序。
我只是使用MAC地址生成请求密钥,然后要求用户向您的客户端注册。您的客户端将具有一个特殊的应用程序,该应用程序将使用该请求密钥并生成一个激活密钥,然后用户可以使用该激活密钥来激活软件。激活后,该软件就可以正常工作,而无需偶尔打电话回去进行验证等。
那是不是一个真正的要求。我的首要任务是尝试说服客户这是一个坏主意。
原因是这些方案实际上从不阻止您的代码被破解。但是,它们确实使您真正的客户的生活更加艰难。我发现很难想到有任何其他行业会用永远无法实现其目标的计划来惹恼其真正的客户(当然,除了政府服务:-)。
如果您必须这样做,我将做些象征性的努力来履行合同义务(但是,请不要告诉您的客户)。将MAC地址(或随机数,如果$DEITY
计算机没有网卡,则为随机数)作为请求密钥,并使用一个程序将XOR
其与ASCII字符串一起使用以获取激活密钥,这似乎是一种可行的方法。我还要存储这两个密钥,因为如果您只是想更改网卡(甚至是主板),就不希望该软件停用,因为它们仍然可以看作是同一台计算机,并且如果软件停止工作也不高兴。
无论如何,您的代码都将被破解(除非程序是垃圾,我敢肯定不是这种情况)-如果您的客户的公司以某种方式不响应,此方法将为您的真正客户提供将其软件迁移到另一台计算机的途径(下降支持) ,倒闭等)。
所有依赖于一点硬件唯一性的方案的主要麻烦在于,客户可能选择更改那部分硬件:
将其磁盘内容重影到更大的硬盘上会使HD序列号发生变化。
使用CPU序列号意味着升级到最新的Intel bigmutha CPU会杀死您的软件。
使用MAC地址意味着他们无法更改其NIC。
所有这些都可以通过在安装时使用这些值来创建密钥来解决,并且仅对照该密钥进行检查,而不用检查六个月后的更改值。这意味着您必须存储请求和激活值,但是升级将不需要您的用户完成重新激活其软件的过程。相信我,他们会因为这样做而鄙视您。