如何生成软件许可证密钥?

许可证密钥是反盗版措施的事实标准。 说实话,这使我感到安全通过朦胧 ,虽然我真的不知道如何生成许可证密钥。 什么是许可证密钥生成的好(安全)例子? 他们使用什么encryption原语(如果有的话)? 这是一个消息摘要? 如果是的话,他们将哈希数据? 开发人员采用什么方法来使破解者难以build立自己的密钥生成器? 密钥生成器是如何制作的?

对于老派的CD密钥,这只是一个构成一个algorithm的问题,CD密钥(可以是任何string)很容易生成并且容易validation,但是有效CD密钥与无效CD的比率键太小,随机猜测CD键不太可能让你有效。

不正确的做法:

星际争霸半条命都使用了相同的校验和,第13位validation了第12位。因此,您可以input前12位数字的任何内容,并猜测第13位(只有10个可能性),导致臭名昭着的1234-56789-1234

validationalgorithm是公开的,看起来像这样:

 x = 3; for(int i = 0; i < 12; i++) { x += (2 * x) ^ digit[i]; } lastDigit = x % 10; 

正确的方式去做

Windows XP需要相当多的信息,encryption它,并把字母/数字编码放在一个贴纸上。 这允许MS同时validation您的密钥获得产品types(家庭,专业等)。 另外,它需要在线激活。
完整的algorithm相当复杂,但在德国出版的这个 (完全合法!)论文中很好地概括了。

当然,不pipe你做什么,除非你提供在线服务(如“魔兽世界” ),任何types的版权保护只是一个摊位:不幸的是,如果任何游戏都值得,有人会破坏 CD密钥algorithm以及所有其他版权保护。

真正正确的方法:

对于在线服务来说,生活要简单一些,因为即使使用二进制文件,您也需要通过服务器进行身份validation来使用它(例如,拥有一个WoW帐户)。 例如,在购买游戏时间卡时使用的“魔兽世界”的CD密钥algorithm可能看起来像这样:

  1. 生成一个非常大的密码安全的随机数。
  2. 将其存储在我们的数据库中并打印在卡上。

    然后,当有人input一个播放卡号码时,检查它是否在数据库中,如果是,将该号码与当前用户关联,以便它不能再次使用。

对于在线服务,没有理由使用上述scheme; 使用其他任何东西都可能导致问题 。

当我最初编写这个答案的时候,假设问题是关于许可证密钥的“离线”validation。 其他大多数答案都是针对在线validation,而这种处理要容易得多(大部分逻辑可以在服务器端完成)。

通过离线validation,最困难的事情是确保您可以生成大量的唯一许可证密钥,并且仍然保持一个不易受影响的强大algorithm(如简单的校验位)

我对math并不是很熟练,但是让我觉得有一个办法是使用一个math函数绘制一个图

绘制线可以有(如果您使用足够的频率)成千上万的独特点,所以你可以通过在该图上select随机点并以某种方式编码值来生成密钥

在这里输入图像描述

作为一个例子,我们将绘制这个图,select四个点,并将其编码为“0,-500; 100,-300; 200,-100; 100,600”

我们将用一个已知和固定的密钥encryptionstring(可怕的是弱,但它是有用的 ),然后通过Base32转换结果字节以生成最终密钥

然后应用程序可以逆转这个过程(base32为实数,解密,解码点),然后检查每个点在我们的秘密图上。

它的代码量非常小,可以生成大量的唯一有效密钥

然而,这是非常安全的默默无闻。 任何花时间拆解代码的人都能够findgraphics函数和encryption密钥,然后模拟一个密钥生成器,但是它可能对于减缓随机盗版非常有用。

请参阅关于部分密钥validation的文章,其中包括以下要求:

  • 许可证密钥必须足够简单才能input。

  • 我们必须能够在被盗用的信用卡退款或购买的情况下黑名单(撤销)一个许可证密钥。

  • 没有“打电话回家”来testing密钥。 虽然这种做法变得越来越普遍,但我仍然不认为它是一个用户,所以不会要求我的用户忍受它。

  • 一个黑客应该不可能反汇编我们发布的应用程序,并从中产生一个工作“关键”。 这意味着我们的应用程序不会完全testingvalidation的密钥。 只有一些关键是要testing。 此外,应用程序的每个版本都应testing密钥的不同部分,以便基于早期版本的假密钥在我们的软件的更高版本中不起作用。

  • 重要提示:合法用户不可能无意中键入一个无效的密钥,该密钥似乎可以正常工作,但是由于印刷错误,将会在将来的版本上失败。

我还没有什么人的经验来制作CD密钥,但是(假设你不想走在线激活的道路上),可以通过几种方法来制作一个关键:

  • 要求数字可以被17所整除。微不足道的猜测,如果你有权访问许多键,但大多数潜在的string将是无效的。 类似的会要求密钥的校验和匹配一个已知的值。

  • 要求键的前半部分与已知值连接时,缩减到键的后半部分。 更好,但程序仍然包含生成密钥所需的所有信息以及validation它们。

  • 通过使用私钥encryption一个已知的值+随机数来生成密钥。 这可以通过使用相应的公钥进行解密并validation已知值来validation。 现在程序有足够的信息来validation密钥而不能生成密钥。

这些仍然是全部可以攻击的:程序仍然在那里,可以打补丁绕过检查。 Cleverer可能会使用我的第三种方法中的已知值encryption部分程序,而不是将值存储在程序中。 这样,在解密程序之前,您必须先find密钥的副本,但是一旦解密后仍然可能被复制,并让一个人拿走他们合法的副本并使用它来让其他人访问该软件。

CD-Key对于任何非联网的东西来说都不是很安全,所以在技术上它们不需要被安全地生成。 如果你使用.net,你几乎可以用Guid.NewGuid()。

他们现在的主要用途是用于Multiplayer组件,服务器可以validationCD Key。 为此,它是多么安全的生成它并不重要,因为它归结为“查找传入的内容,并检查是否有其他人正在使用它”。

这就是说,你可能想要使用一个algorithm来实现两个目标:

  • 有一些校验和。 这可以让你的安装程序显示“密钥似乎不是有效”的消息,只是为了检测错别字(在安装程序中添加这样的检查实际上意味着编写密钥生成器是微不足道的,因为黑客有他需要的所有代码。检查并完全依靠服务器端validation将禁用该检查,冒着不理解为什么服务器不接受其CD密钥的合法客户的风险,因为他们不知道错字)
  • 使用有限的字符子集。 尝试键入一个CD键,并猜测“这是一个8还是B?1或I?Q或O或0? – 通过使用非模糊字符/数字的子集,可以消除这种混淆。

话虽如此,你仍然希望有一个大的分布和一些随机性,以避免海盗只是猜测一个有效的密钥(这是在你的数据库中是有效的,但仍然在商店货架上的一个盒子里),并拧上一个合法的客户, 。

如果你不特别关心密钥的长度,一个相当有效的方法就是使用公钥和私钥encryption。

基本上有一些nonce和一个固定的签名。

例如:0001-123456789

0001是你的随机数,123456789是你的固定签名。

然后使用您的私钥对此进行encryption,以获取您的CD密钥,如下所示:ABCDEF9876543210

然后分配您的应用程序的公钥。 公钥可以用来解密CD密钥“ABCDEF9876543210”,然后validation固定签名部分。

这样就可以防止有人猜测CD关键字是否为nonce 0002,因为他们没有私钥。

唯一主要的缺点是在使用大小为1024位的私钥/公钥时,您的CD密钥会很长。 你还需要select一个足够长的时间,这样你就不会encryption一小琐碎的信息。

最重要的是,这种方法将工作没有“激活”,您可以使用的东西,如电子邮件地址或被许可人名称作为现时。

关键系统必须有几个属性:

  • 很less的钥匙必须是有效的
  • 即使给予用户所有的东西,也不能推导出有效的密钥。
  • 一个系统上的有效密钥不是另一个系统上的有效密钥。
  • 其他

应该给你的解决scheme之一是使用公钥签名scheme 。 从一个“系统散列”开始(比如抓取所有网卡上的MAC,sorting,CPU-ID信息,以及其他一些东西,将它们连接在一起,并取得结果的MD5(你真的不想成为处理个人识别信息,如果你不需要))追加CD的序列号,并拒绝启动,除非某些registry项(或某些数据文件)具有有效的blob签名。 用户通过将Blob发送给您来激活程序,并将签名寄回。

潜在的问题包括你提供几乎所有的签名,所以你需要假设有人会运行一个明文和/或select的密文攻击。 这可以通过检查提供的序列号和拒绝处理来自无效请求的请求以及拒绝在给定的时间间隔(例如每年2次)处理超过给定数量的查询来缓解,

我应该指出一些事情:首先,一个熟练和坚定的攻击者将能够绕过他们无限制访问的部分( CD上的所有内容)的任何和所有安全性,那么您可以在该帐户上做的最好的使得获取非法访问比获得合法访问更困难。 其次,我不是专家,所以在这个提议的scheme中可能会有严重的缺陷。

所有的CD都只是保护诚实用户的防护algorithm,而不提供任何防盗版保护。

“盗版者”只需要访问一张合法的光盘及其存取码,然后就可以制作n张副本并分发。

无论您如何使用密码保护代码,都无关紧要,您需要以纯文本forms提供CD,否则合法用户无法激活该软件。

大多数安全scheme涉及用户向软件供应商提供运行该软件的机器的某些细节(CPU序列号,MAC地址,IP地址等),或者要求在线访问以在供应商网站上注册软件作为回报接收激活令牌。 第一个选项需要大量的手动pipe理,只有非常高价值的软件才值得,第二个选项可能被欺骗,如果networking访问受限,或者被阻止在防火墙之后,则会被绝对地激怒。

总的来说,与您的客户build立信任关系要容易得多!

还有一些DRM行为将多个步骤结合在一起。 最着名的例子之一就是Adobevalidation其Creative Suite安装的方法之一。 使用这里讨论的传统CD Key方法,然后调用Adobe的支持线。 CD代码被提供给Adobe代表,并且他们返回一个激活号码供用户使用。

然而,尽pipe被分解成步骤,但是这与通常的过程中使用的裂化方法相同。 用于创build相对于原始CD密钥检查的激活密钥的过程很快就被发现,并且包含两个密钥的发生器都被制造出来。

但是,这种方法仍然存在,作为用户没有互联网连接来validation产品的方式。 outlook未来,随着互联网访问的普及,很容易看到这些方法将如何消除。