roo*_*ook 349 security cryptography license-key
许可证密钥是作为反盗版措施的事实标准.说实话,这让我觉得安全通过Obscurity,虽然我真的不知道如何生成许可证密钥.什么是许可密钥生成的好(安全)示例?他们使用什么加密原语(如果有的话)?这是消息摘要吗?如果是这样,他们会散列什么数据?开发人员采用了哪些方法来使破解者难以构建自己的密钥生成器?关键发电机是如何制造的?
Blu*_*eft 262
对于老式CD密钥,只需要编写一个算法,CD密钥(可以是任何字符串)易于生成且易于验证,但有效CD密钥与无效CD的比例-keys很小,随机猜测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;
Run Code Online (Sandbox Code Playgroud)
Windows XP需要相当多的信息,对其进行加密,并将字母/数字编码放在标签上.这允许MS同时验证您的密钥并获得产品类型(Home,Professional等).此外,它需要在线激活.
完整的算法相当复杂,但在德国出版的这篇(完全合法!)论文中很好地概述了.
当然,无论你做什么,除非你提供在线服务(如魔兽世界),任何类型的复制保护只是一个失速:不幸的是,如果它是任何值得的游戏,有人会破坏(或至少规避) CD密钥算法,以及所有其他版权保护.
对于在线服务,生活稍微简单一些,因为即使使用二进制文件,您也需要对其服务器进行身份验证以对其进行任何使用(例如,拥有魔兽帐户).魔兽世界的CD密钥算法 - 例如,在购买游戏时卡时使用 - 可能看起来像这样:
- 生成一个非常大的加密安全随机数.
- 将其存储在我们的数据库中并将其打印在卡上.
然后,当有人输入游戏时间卡号时,检查它是否在数据库中,如果是,则将该号码与当前用户关联,以便永远不会再次使用它.
对于在线服务,没有理由不使用上述方案; 使用其他任何东西都可能导致问题.
Pau*_*ulG 55
当我最初写这个答案时,假设问题是关于许可证密钥的"离线"验证.大多数其他答案都涉及在线验证,这更容易处理(大多数逻辑可以在服务器端完成).
通过离线验证,最困难的事情是确保您可以生成大量独特的许可证密钥,并且仍然保持一个不易受到破坏的强大算法(例如简单的校验位)
我不是很精通数学,但让我感到震惊的是,一种方法是使用绘制图形的数学函数
绘制的线可以具有(如果使用足够精细的频率)数千个独特点,因此您可以通过在该图上选择随机点并以某种方式对值进行编码来生成键

举个例子,我们将绘制这个图,选择四个点并编码成一个字符串为"0,-500; 100,-300; 200,-100; 100,600"
我们将使用已知和固定密钥加密字符串(非常弱,但它有用),然后通过Base32转换结果字节以生成最终密钥
然后,应用程序可以反转此过程(base32为实数,解密,解码点),然后检查每个点是否在我们的秘密图上.
它只有相当少的代码,可以生成大量独特有效的密钥
然而,默默无闻是非常安全的.任何花时间反汇编代码的人都可以找到图形功能和加密密钥,然后模拟一个密钥生成器,但它可能对减慢随意盗版非常有用.
The*_*can 32
检查有关部分密钥验证的 tis文章,其中包含以下要求:
许可证密钥必须足够容易输入.
在退款或使用被盗信用卡购物的情况下,我们必须能够将许可证密钥列入黑名单(撤销).
没有"打电话回家"来测试密钥.虽然这种做法越来越普遍,但我仍然不喜欢它作为用户,因此不会要求我的用户忍受它.
破解者不应该拆解我们发布的应用程序并从中生成一个有效的"keygen".这意味着我们的应用程序无法完全测试验证密钥.只有部分密钥需要测试.此外,应用程序的每个版本都应该测试密钥的不同部分,以便基于早期版本的虚假密钥不会对我们软件的更高版本起作用.
重要提示:合法用户不应该意外地键入一个看似有效的无效密钥,但由于印刷错误而导致未来版本失败.
And*_*ett 21
我没有任何关于人们实际生成CD密钥的经验,但是(假设你不想在网上激活的道路上)这里有一些方法可以制作密钥:
要求数字可以被(例如)整除.17.如果你有许多键可以访问,那么很容易猜测,但是大多数潜在的字符串都是无效的.类似的是要求密钥的校验和与已知值匹配.
要求密钥的前半部分在与已知值连接时,深入到密钥的后半部分.更好,但程序仍然包含生成密钥以及验证密钥所需的所有信息.
通过加密(使用私钥)已知值+ nonce来生成密钥.这可以通过使用相应的公钥解密并验证已知值来验证.该程序现在有足够的信息来验证密钥而无法生成密钥.
这些仍然可以攻击:程序仍在那里,可以修补以绕过检查.Cleverer可能是使用我的第三种方法中的已知值加密程序的一部分,而不是将值存储在程序中.这样你就必须在解密程序之前找到密钥的副本,但它仍然容易被解密后复制并让一个人拿走他们的合法副本并使用它来让其他人访问该软件.
Mic*_*tum 17
CD-Keys对于任何非联网的东西都没有太大的安全性,因此从技术上讲,它们不需要安全地生成.如果你在.net上,你几乎可以使用Guid.NewGuid().
它们现在主要用于多人游戏组件,服务器可以在其中验证CD密钥.为此,它的生成安全性并不重要,因为它归结为"查找传入的内容并检查其他人是否已经在使用它".
话虽这么说,你可能想用算法来实现两个目标:
话虽这么说,你仍然想要一个大的分布和一些随机性,以避免海盗只是猜测一个有效的密钥(这在你的数据库中有效,但仍然在商店货架上的一个盒子里),并拧紧碰巧购买该盒子的合法客户.
use*_*erx 10
如果您不是特别关心密钥的长度,那么一种非常可靠且真实的方法是使用公钥和私钥加密.
基本上有某种nonce和固定签名.
例如:0001-123456789
其中0001是你的随机数,123456789是你的固定签名.
然后使用您的私钥对其进行加密,以获取您的CD密钥,如下所示:ABCDEF9876543210
然后使用您的应用程序分发公钥.公钥可用于解密CD密钥"ABCDEF9876543210",然后您可以验证其固定签名部分.
这样就可以防止有人猜测nonce 0002的CD密钥是什么,因为它们没有私钥.
唯一的主要缺点是当使用1024位大小的私钥/公钥时,你的CD密钥会很长.您还需要选择一个足够长的随机数,这样您就不会加密大量的信息.
好的一面是,这种方法可以在没有"激活"的情况下工作,您可以使用电子邮件地址或被许可人名称等字符作为随机数.
密钥系统必须具有以下几个属性:
应该给你这些的一个解决方案是使用公钥签名方案.从"系统哈希"开始(比如抓住任何网卡上的mac,排序,以及CPU-ID信息,加上其他一些东西,将它们连接在一起并获取结果的MD5(你真的不想成为处理个人身份信息,如果您不必))附加CD的序列号并拒绝启动,除非某些注册表项(或某些数据文件)具有该blob的有效签名.用户通过向您发送blob来激活程序,然后您将回溯签名.
潜在的问题包括您提出几乎任何标志,因此您需要假设某人将运行选定的纯文本和/或选择的密文攻击.这可以通过检查提供的序列号并拒绝处理来自无效序列号的请求以及拒绝在一个间隔(例如每年2个)中处理来自给定s/n的给定数量的查询来减轻
我应该指出一些事项:首先,熟练且坚定的攻击者将能够绕过他们无限制访问的部分中的任何和所有安全性(即 CD上的所有内容),您可以在该帐户上做的最好的是使得获取非法访问权限比获得合法访问权限更难.其次,我不是专家,所以这个提议的方案可能存在严重的缺陷.
我意识到这个答案大约晚了十年。
一个好的软件许可证密钥/序列号生成器不仅仅包含一串随机字符或来自某个曲线生成器的值。使用有限的字母数字字母表,数据可以嵌入到一个短字符串中(例如 XXXX-XXXX-XXXX-XXXX),其中包括各种有用的信息,例如:
然后,许可证密钥数据被加密,然后使用有限的字母数字字母表进行编码。对于在线验证,许可证服务器保存用于解密信息的秘密。对于离线验证,解密秘密与解密/验证代码一起包含在软件本身中。显然,离线验证意味着该软件对于制作注册机的人来说并不安全。
创建许可证密钥最困难的部分可能是弄清楚如何将尽可能多的数据塞进尽可能少的字节中。请记住,用户将手动输入许可证密钥,因此每一位都很重要,用户不想输入极长、复杂的字符串。16 到 25 个字符的许可证密钥是最常见的,并且平衡了可以放置的数据量比较密钥与用户输入密钥解锁软件的容忍度。将字节分割成位块可以包含更多信息,但确实增加了生成器和验证器的代码复杂性。
加密是一个复杂的话题。一般来说,AES 等标准加密算法的块大小与保持许可证密钥长度较短的目标不符。因此,大多数制作自己的许可证密钥的开发人员最终都会编写自己的加密算法(这种活动经常被劝阻)或者根本不加密密钥,这保证了有人会编写密钥生成器。可以说,良好的加密很难做到正确,而对 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
上述License服务器支持在线和离线两种验证方式。软件产品可能仅通过在线验证开始存在。当软件产品准备退役并且不再受支持时,它可以轻松地转移到离线验证,一旦用户升级到切换到离线验证的软件的最后一个版本,所有现有密钥都将继续工作。
可以在此处找到如何将上述许可证服务器集成到网站中以销售软件许可证以及可安装的演示应用程序的现场演示(网站和演示应用程序也是开源的):
https://license-server-demo.cubiclesoft.com/
全面披露:我是许可证服务器和演示站点软件的作者。