许可证密钥是作为反盗版措施的事实标准。说实话,这让我觉得(in)Security Through Obscurity,虽然我真的不知道如何生成许可证密钥。什么是许可密钥生成的好(安全)示例?他们使用什么加密原语(如果有的话)?这是消息摘要吗?如果是这样,他们会散列什么数据?开发人员采用了哪些方法来使破解者难以构建自己的密钥生成器?密钥生成器是如何制作的?
答案 0 :(得分:260)
对于老式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同时验证您的密钥和是否同时获得产品类型(Home,Professional等)。此外,它需要在线激活 完整的算法相当复杂,但在德国出版的this(完全合法!)论文中很好地概述了。
当然,无论你做什么,除非你提供在线服务(如魔兽世界),任何类型的版权保护只是一个档位:不幸的是,如果它是任何游戏价值值,有人会打破(或至少规避) CD密钥算法,以及所有其他版权保护。
对于在线服务,生活有点简单,因为即使使用二进制文件,您也需要对其服务器进行身份验证以对其进行任何使用(例如,拥有魔兽帐户)。 “魔兽世界”的CD密钥算法 - 例如,在购买娱乐时卡时使用 - 可能看起来像这样:
- 生成一个非常大的加密安全随机数。
- 将其存储在我们的数据库中并将其打印在卡上。
醇>
然后,当有人输入游戏时间卡号时,检查它是否在数据库中,如果是,则将该号码与当前用户关联,以便永远不会再次使用。
对于在线服务,不没有理由使用上述方案;使用其他任何东西都可以lead to problems。
答案 1 :(得分:52)
当我最初写这个答案时,假设问题是关于许可证密钥的“离线”验证。大多数其他答案都涉及在线验证,这更容易处理(大多数逻辑可以在服务器端完成)。
通过离线验证,最困难的事情是确保您可以生成大量独特的许可证密钥,并且仍然保留一个不易受到损害的强大算法(例如简单的校验位)
我对数学并不十分精通,但让我感到震惊的是,一种方法是使用绘制图形的mathematical function
绘制的线条可以具有(如果使用足够精细的频率)数千个独特点,因此您可以通过在该图形上选择随机点并以某种方式对值进行编码来生成键
举个例子,我们将绘制这个图,选择四个点并编码成一个字符串为“0,-500; 100,-300; 200,-100; 100,600”
我们将使用已知且固定的密钥加密字符串(非常弱,但它有用),然后将结果字节转换为Base32以生成最终密钥
然后,应用程序可以反转此过程(base32为实数,解密,解码点),然后检查每个点是否在我们的秘密图上。
它的代码数量相当少,可以生成大量唯一且有效的密钥
然而,默默无闻是非常安全的。任何花时间反汇编代码的人都可以找到图形函数和加密密钥,然后模拟密钥生成器,但它可能对减慢随意盗版非常有用。
答案 2 :(得分:31)
检查Partial Key Verification上涉及以下要求的条款:
许可证密钥必须足够容易输入。
我们必须能够在使用被盗信用卡进行退单或购物的情况下将许可证密钥列入黑名单(撤销)。
没有“打电话回家”来测试密钥。虽然这种做法越来越普遍,但我仍然不喜欢它作为用户,因此不会要求我的用户忍受它。
破解者不应该拆解我们发布的应用程序并从中生成一个有效的“keygen”。这意味着我们的应用程序无法完全测试验证密钥。只有部分密钥需要测试。此外,应用程序的每个版本都应该测试密钥的不同部分,以便基于早期版本的虚假密钥不适用于我们软件的更高版本。
重要提示:合法用户不应意外输入无效密钥,该密钥似乎有效,但由于印刷错误而导致未来版本失败。
答案 3 :(得分:21)
我没有任何关于人们实际生成CD密钥的经验,但是(假设你不想走在网上激活的道路上),这里有一些方法可以制作密钥:
要求该数字可以被(例如)整除.17。如果您可以访问许多键,但是大多数潜在的字符串都无效,那就很容易猜到。类似的是要求密钥的校验和与已知值匹配。
要求密钥的前半部分与已知值连接时,深入到密钥的后半部分。更好,但程序仍然包含生成密钥以及验证密钥所需的所有信息。
通过加密(使用私钥)已知值+ nonce来生成密钥。这可以通过使用相应的公钥解密并验证已知值来验证。该程序现在有足够的信息来验证密钥而无法生成密钥。
这些仍然可以攻击:程序仍在那里,可以修补以绕过检查。 Cleverer可能是使用我的第三种方法中的已知值加密程序的一部分,而不是将值存储在程序中。这样你就必须在解密程序之前找到密钥的副本,但它仍然容易被解密后复制并让一个人拿走他们的合法副本并使用它来让其他人访问该软件。
答案 4 :(得分:18)
CD-Keys对于任何非联网的东西都没有太大的安全性,因此从技术上讲,它们不需要安全地生成。如果你在.net上,几乎可以使用Guid.NewGuid()。
现在它们主要用于多人游戏组件,服务器可以在其中验证CD密钥。为此,它的生成安全性并不重要,因为它归结为“查找传入的内容并检查其他人是否已经在使用它”。
话虽这么说,你可能想用算法实现两个目标:
话虽这么说,你仍然想要一个大的发行版和一些随机性,以避免海盗只是猜测一个有效的密钥(这在你的数据库中有效,但仍然在商店货架上的一个盒子里)并拧紧一个合法的客户碰巧买那个盒子。
答案 5 :(得分:10)
如果你不是特别关心密钥的长度,那么一种非常可靠且真实的方法是使用公钥和私钥加密。
基本上有某种nonce和固定签名。
例如: 0001-123456789
其中0001是您的nonce,123456789是您的固定签名。
然后使用您的私钥加密它以获取您的CD密钥,如下所示: ABCDEF9876543210
然后使用您的应用程序分发公钥。公钥可用于解密CD密钥“ABCDEF9876543210”,然后您可以验证其固定签名部分。
这样可以防止有人猜测nonce 0002的CD密钥是什么,因为他们没有私钥。
唯一的主要缺点是当使用1024位大小的私钥/公钥时,您的CD密钥会很长。您还需要选择一个足够长的随机数,这样您就不会加密大量的信息。
好的一面是,这种方法无需“激活”即可使用,您可以使用电子邮件地址或被许可人名称等字符作为随机数。
答案 6 :(得分:9)
密钥系统必须具有多个属性:
应该为您提供的一个解决方案是使用public key signing scheme。从“系统哈希”开始(比如抓住任何网卡上的mac,排序,以及CPU-ID信息,加上其他一些东西,将它们连接在一起并获取结果的MD5(你真的不想成为处理personally identifiable information如果您不必))附加CD的序列号并拒绝启动,除非某些注册表项(或某些数据文件)具有该blob的有效签名。用户通过将blob发送给您来激活程序,然后您将回溯签名。
潜在问题包括您提出几乎任何标志,因此您需要假设有人会发起chosen plain text和/或chosen ciphertext攻击。这可以通过检查提供的序列号并拒绝处理来自无效序列号的请求以及拒绝在一个间隔(例如每年2个)中处理来自给定s / n的给定数量的查询来减轻
我应该指出一些事项:首先,熟练且坚定的攻击者将能够绕过他们无限制访问的部分中的任何和所有安全性(即 CD上的所有内容) ,你可以在该帐户上做的最好的事情是使得获取非法访问权限比获得合法访问权限更难。其次,我不是专家,所以这个提议的方案可能存在严重的缺陷。
答案 7 :(得分:1)
还有一些DRM行为包含了流程的多个步骤。其中一个最着名的例子是Adobe用于验证其Creative Suite安装的方法之一。使用此处讨论的传统CD Key方法,然后调用Adobe的支持热线。 CD密钥将提供给Adobe代表,他们会返回一个供用户使用的激活码。
然而,尽管分解为步骤,但这仍然成为用于正常过程的相同裂缝方法的牺牲品。用于创建根据原始CD密钥检查的激活密钥的过程很快被发现,并且生成了包含两个密钥的生成器。
但是,对于没有互联网连接的用户来说,此方法仍然存在以验证产品。展望未来,随着互联网接入无处不在,很容易看出这些方法将如何消除。
答案 8 :(得分:1)
所有仅限CD的复制保护算法都不会使诚实用户感到不安,同时也无法防止盗版。
“盗版者”只需要访问一个合法的CD及其访问代码,然后他就可以制作n份并分发它们。
无论加密安全如何制作代码,您都需要以纯文本形式提供CD,或者合法用户无法激活软件。
大多数安全方案涉及用户向软件供应商提供将运行软件的机器的一些细节(cpu序列号,mac地址,IP地址等),或者要求在线访问以在软件上注册软件。供应商网站并作为回报获得激活令牌。第一个选项需要大量的人工管理,并且仅对非常高价值的软件有价值,第二个选项可能是欺骗性的,如果您的网络访问受限或者您被困在防火墙后,则绝对令人愤怒。
总的来说,与客户建立信任关系要容易得多!
答案 9 :(得分:1)
我知道这个答案对党来说要晚10年了。
一个好的软件许可证密钥/序列号生成器不仅仅包含一串随机字符或某个曲线生成器的值。使用有限的字母数字字母,可以将 data 嵌入到包含所有有用信息的短字符串(例如XXXX-XXXX-XXXX-XXXX)中,
然后对许可证密钥数据进行加密,然后使用有限的字母数字字母进行编码。对于在线验证,许可证服务器保留用于解密信息的机密。对于脱机验证,软件本身包含解密秘密以及解密/验证代码。显然,离线验证意味着该软件对于有人进行密钥生成是不安全的。
关于创建许可证密钥的最困难的部分可能是弄清楚如何将尽可能多的数据填充到尽可能少的字节中。请记住,用户将手动输入许可证密钥,因此每一位都很重要,用户不想输入非常长且复杂的字符串。最常见的是16到25个字符的许可证密钥,可以平衡可放置多少数据密钥与用户对输入密钥以解锁软件的容忍度之间的关系。将字节切成位块可以包含更多信息,但确实会增加生成器和验证器的代码复杂性。
加密是一个复杂的主题。通常,诸如AES之类的标准加密算法的块大小与保持许可证密钥长度较短的目标不符。因此,大多数使用自己的许可证密钥的开发人员最终都会编写自己的加密算法(an activity which is frequently discouraged)或根本不加密密钥,这保证了有人会编写密钥生成器。可以说,良好的加密很难正确完成,并且对Feistel网络和现有密码的工作方式有充分的了解是先决条件。
验证密钥是对字符串进行解码和解密,验证哈希/校验和,检查数据中的产品ID和主要版本号和次要版本号,验证许可证尚未过期以及进行任何其他检查的问题需要执行。
编写密钥生成器是了解许可证密钥包含什么,然后产生与原始密钥生成器产生的相同输出的问题。如果软件中包含并使用了许可证密钥验证算法,则只需创建与验证过程相反的软件即可。
要查看整个过程是什么样子,这是我最近写的一篇博客文章,内容涉及选择许可证密钥长度,数据布局,加密算法和最终编码方案:
https://cubicspot.blogspot.com/2020/03/adventuring-deeply-into-software-serial.html
可以在此处看到来自博客文章的密钥生成器和密钥验证程序的实际实用实现:
https://github.com/cubiclesoft/php-misc/blob/master/support/serial_number.php
上述课程的文档:
https://github.com/cubiclesoft/php-misc/blob/master/docs/serial_number.md
可以使用以下序列号代码生成和管理许可证密钥的可立即投入生产的开源许可证服务器:
https://github.com/cubiclesoft/php-license-server
以上许可证服务器支持联机和脱机验证模式。软件产品可能仅通过在线验证而开始存在。当该软件产品准备退休并且不再受支持时,它可以轻松地移至脱机验证,一旦用户升级到该软件的最新版本(切换到脱机验证),所有现有密钥将继续起作用。
可以在此处找到有关如何将上述许可证服务器集成到网站中以出售软件许可证的实时演示以及可安装的演示应用程序(该网站和演示应用程序也是开源的):
https://license-server-demo.cubiclesoft.com/
全部披露:我是许可证服务器和演示站点软件的作者。
答案 10 :(得分:0)
您可以使用它在您的软件项目中非常容易地使用和实现安全许可API,(您需要下载桌面应用程序以从https://www.systemsoulsoftwares.com/创建安全许可)