软件许可证密钥如何生成?
许可证密钥是反盗版措施的事实标准。 说实话,这使我感到(安全)通过朦胧,虽然我真的不知道如何生成许可证密钥。 什么是许可证密钥生成的好(安全)示例? 他们使用什么加密原语(如果有的话)? 它是一个消息摘要? 如果是这样,他们将哈希数据是什么? 开发人员采用什么方法来使破解者难以建立自己的密钥生成器? 密钥生成器是如何制作的?
对于老派的CD密钥,这只是一个制作算法的问题,CD密钥(可以是任何字符串)很容易生成并且容易验证,但是有效CD密钥与无效CD的比率键太小,以至于随机猜测CD键不太可能让你成为有效的键。
不正确的做法:
星际争霸和半条命都使用了相同的校验和,第13位数字验证了前12位。因此,您可以输入前12位数字的任何内容,并猜测第13位(只有10种可能性),导致臭名昭着的1234-56789-1234
验证算法是公开的,看起来像这样:
x = 3;
for(int i = 0; i < 12; i++)
{
x += (2 * x) ^ digit[i];
}
lastDigit = x % 10;
正确的方式去做
Windows XP需要相当多的信息,对其进行加密,并将字母/数字编码放在贴纸上。 这允许MS同时验证您的密钥并获得产品类型(家庭版,专业版等)。 此外,它需要在线激活。
完整的算法相当复杂,但在德国出版的这篇(完全合法!)论文中很好地概括了。
当然,不管你做什么,除非你提供在线服务(如魔兽世界 ),任何类型的版权保护只是一个摊位:不幸的是,如果它是任何有价值的游戏,有人会打破(或至少绕过)CD密钥算法以及所有其他版权保护。
真正正确的方法:
对于在线服务来说,生活要简单一些,因为即使使用二进制文件,您需要通过服务器进行身份验证才能使用它(例如,拥有一个WoW帐户)。 例如,在购买游戏时间卡时使用的魔兽世界的CD密钥算法可能看起来像这样:
然后,当有人输入播放卡号码时,检查它是否在数据库中,如果是,将该号码与当前用户关联,以便它永远不会再被使用。
对于在线服务,没有理由不使用上述方案; 使用其他任何东西都会导致问题。
当我最初编写这个答案时,假设问题是关于许可证密钥的“离线”验证。 其他大多数答案都提供了在线验证,这可以更容易地处理(大多数逻辑可以在服务器端完成)。
通过离线验证,最困难的事情是确保您可以生成大量唯一的许可证密钥,并且仍然保持一种不易受影响的强大算法(例如简单的校验位)
我对数学并不是很熟练,但是让我感到有一种方法是使用绘制图的数学函数
绘制的线可以(如果使用足够好的频率)成千上万个独特的点,所以您可以通过在该图上选取随机点并以某种方式对值进行编码来生成密钥
作为一个例子,我们将绘制该图,挑选4个点并将其编码为“0,-500; 100,-300; 200,-100; 100,600”
我们将用一个已知的和固定的密钥来加密字符串(非常微弱,但它有用),然后通过Base32转换结果字节以生成最终密钥
然后应用程序可以逆转这个过程(base32为实数,解密,解码点),然后检查每个点在我们的秘密图上。
它的代码量非常小,可以生成大量唯一且有效的密钥
无论如何,它是非常安全的。 任何花时间分解代码的人都可以找到图形函数和加密密钥,然后模拟一个密钥生成器,但它可能对于减缓随机盗版非常有用。
请查看关于部分密钥验证的文章,其中包含以下要求:
许可证密钥必须足够简单才能输入。
我们必须能够在被盗信用卡退款或购买的情况下将黑名单(撤销)许可证密钥。
没有“打电话回家”来测试密钥。 虽然这种做法变得越来越流行,但我仍然不认为它是一个用户,所以不会要求我的用户忍受它。
一个黑客应该不可能反汇编我们发布的应用程序,并从中产生一个可用的“keygen”。 这意味着我们的应用程序不会完全测试验证的密钥。 只有一些关键是要测试。 此外,应用程序的每个版本都应该测试密钥的不同部分,以便基于早期版本的假密钥在我们的软件的更高版本中不起作用。
重要提示:合法用户不应该有可能意外键入无效密钥,该密钥看起来可以正常工作,但由于印刷错误而导致未来版本无法使用。