许可证密钥是反盗版措施的标准。老实说,这给我的印象是(见)通过模糊实现安全,尽管我真的不知道许可证密钥是如何生成的。许可证密钥生成的一个好的(安全的)示例是什么?他们使用什么密码原语(如果有的话)?它是消息摘要吗?如果是,他们会哈希哪些数据?开发人员采用什么方法使黑客难以构建他们自己的密钥生成器?密钥生成器是如何制造的?
我对人们如何生成CD密钥没有任何经验,但是(假设你不想走在线激活的道路)这里有一些方法可以生成密钥:
要求数字能被(比如说)17整除。不难猜想,如果您可以访问许多键,但大多数潜在的字符串将是无效的。类似地,要求键的校验和与已知值匹配。
要求键的前半部分在与已知值连接时,向下哈希到键的后半部分。更好,但程序仍然包含生成密钥和验证密钥所需的所有信息。
通过加密(使用私钥)已知值+ nonce生成密钥。这可以通过使用相应的公钥进行解密并验证已知值来验证。程序现在有足够的信息来验证密钥,而不能生成密钥。
这些漏洞仍然容易受到攻击:程序仍然存在,可以通过打补丁绕过检查。更聪明的方法可能是使用第三个方法的已知值加密部分程序,而不是将值存储在程序中。这样,在解密程序之前,你必须找到密钥的副本,但一旦解密,它仍然很容易被复制,并且有一个人拿着他们的合法副本,并使用它使其他人能够访问软件。
cd - key对于任何非网络的东西都不是很安全,所以从技术上讲,它们不需要安全生成。如果你使用的是。net,你几乎可以使用guide . newguid()。
它们现在主要用于多人游戏组件,服务器可以在其中验证CD Key。因此,生成它的安全性并不重要,因为归根结底就是“查找传入的任何东西,并检查其他人是否已经在使用它”。
话虽如此,你可能想要使用算法来实现两个目标:
话虽如此,你仍然需要一个大的分布和一些随机性,以避免盗版只是猜测一个有效的密钥(在你的数据库中是有效的,但仍然在商店货架上的一个盒子里),并欺骗碰巧买了那个盒子的合法客户。
当我最初写下这个答案时,假设这个问题是关于许可证密钥的“离线”验证。大多数其他答案都涉及在线验证,这明显更容易处理(大部分逻辑可以在服务器端完成)。
使用离线验证,最困难的事情是确保你可以生成大量唯一的许可密钥,并且仍然保持一个不容易被破坏的强大算法(例如一个简单的检查数字)。
我不是很精通数学,但它打动了我,这样做的一种方法是使用数学函数绘制图形
绘制的线可以有(如果使用足够精确的频率)数千个唯一点,因此可以通过在图上随机选择点并以某种方式编码值来生成键
例如,我们将绘制这张图,选择四个点并将其编码为字符串“0,-500;100,-300;200,-100;100,600”
我们将用一个已知的固定密钥加密字符串(非常弱,但它有一个目的),然后通过Base32转换结果字节以生成最终密钥
然后应用程序可以反转这个过程(从base32到实数,解密,解码这些点),然后检查这些点是否在我们的秘密图上。
这是一个相当少的代码,将允许生成大量的唯一和有效的密钥
然而,它是非常安全的默默无闻。任何花时间分解代码的人都能够找到绘图函数和加密密钥,然后模拟密钥生成器,但它可能对于减缓随意的盗版非常有用。
对于老式的CD键来说,这只是一个容易生成和验证CD键(可以是任何字符串)的算法的问题,但是有效CD键与无效CD键的比例是如此之小,以至于随机猜测CD键不太可能得到有效的CD键。
星际争霸和半衰期都使用了相同的校验和,其中第13位验证了前12位。因此,你可以为前12位输入任何数字,并猜测第13位(只有10种可能),导致臭名昭著的1234-56789-1234
1234-56789-1234
验证算法是公开的,看起来像这样:
x = 3; for(int i = 0; i < 12; i++) { x += (2 * x) ^ digit[i]; } lastDigit = x % 10;
Windows XP获取相当多的信息,加密它,并将字母/数字编码放在贴纸上。这允许MS同时验证你的密钥而且获得产品类型(家庭,专业等)。此外,它需要在线激活 完整的算法相当复杂,但在德国发表的这(完全合法!)论文中很好地概述了
当然,无论你做什么,除非你提供在线服务(如魔兽世界),任何类型的版权保护都只是一个拖延:不幸的是,如果它是任何有价值的游戏,有人会破坏(或至少规避) CD-key算法,以及所有其他版权保护。
对于在线服务来说,情况要简单一些,因为即使使用二进制文件,你也需要通过服务器的身份验证才能使用它。拥有一个WoW账号)。魔兽世界的CD-key算法——例如,在购买游戏卡时使用——可能看起来像这样:
生成一个非常大的加密安全随机数。 存储在我们的数据库中,并打印在卡片上。 然后,当有人输入游戏时间卡号时,检查它是否在数据库中,如果是,将该号码与当前用户关联,以便它永远不会再次使用
对于在线服务,没有理由不使用上述方案;使用其他任何东西可以导致问题。
密钥系统必须具有以下几个属性:
一个解决方案应该给你这些将使用公钥签署方案。从一个“系统散列”开始(比如获取任何网卡上的mac,排序,以及CPU-ID信息,加上一些其他东西,将它们连接在一起并对结果进行MD5(如果没有必要的话,你真的不想处理个人身份信息))追加CD的序列号并拒绝引导,除非某个注册表键(或一些数据文件)对blob具有有效的签名。用户通过将blob发送给您来激活程序,您将签名发送回来。
潜在的问题包括,你提供签名几乎任何东西,所以你需要假设有人会运行选择纯文本和/或选择密文攻击。可以通过检查提供的序列号并拒绝处理来自无效序列号的请求,以及拒绝在一段时间内(例如每年2次)处理来自给定s/n的超过给定数量的查询来缓解这一问题。
我应该指出几件事:首先,一个熟练和坚定的攻击者将能够绕过他们有不受限制访问的部分的任何和所有安全(即。 CD上的所有内容),最好的你能做的是让它更难获得非法访问,而不是获得合法访问。其次,我不是专家,所以这个提议的方案可能存在严重的缺陷。
如果您不是特别关心密钥的长度,那么使用公钥和私钥加密是一种行之有效的方法。
本质上有某种临时的和固定的签名。
其中0001是您的临时签名,123456789是您的固定签名。
然后在应用程序中分发公钥。公钥可用于解密CD密钥“ABCDEF9876543210”,然后验证其固定签名部分。
这可以防止某人猜测nonce 0002的CD密钥是什么,因为他们没有私钥。
唯一的主要缺点是,当使用1024位的私有/公共密钥时,您的CD密钥将非常长。您还需要选择一个足够长的nonce,这样您就不会加密少量的信息。
好的一面是,这种方法不需要“激活”就可以工作,你可以使用电子邮件地址或被许可方的名称作为临时标识。
还有一些DRM行为将多个步骤合并到流程中。最著名的例子之一是Adobe验证其Creative Suite安装的方法之一。使用这里讨论的传统CD Key方法,然后调用Adobe的支持线。CD密钥将提供给Adobe代表,他们将返回用户使用的激活号码。
然而,尽管被分成了几个步骤,但这与正常过程中使用的破解方法相同。人们很快发现了用于创建与原始CD密钥进行检查的激活密钥的过程,并制作了包含这两个密钥的生成器。
然而,这种方法仍然作为一种没有互联网连接的用户验证产品的方式存在。展望未来,随着互联网接入变得无处不在,很容易看到这些方法将被淘汰。
所有的CD拷贝保护算法给诚实的用户带来不便,同时没有提供任何防止盗版的保护。
“盗版者”只需要获得一张合法的cd及其访问代码,他就可以制作n份拷贝并分发它们。
无论代码的加密安全性如何,都需要以明文形式提供CD,否则合法用户无法激活该软件。
最安全的方案包括用户向软件供应商提供运行软件的机器的一些详细信息(cpu序列号、mac地址、Ip地址等),或者要求在线访问在供应商网站上注册软件,并获得激活令牌。第一种方法需要大量的手工管理,只适用于非常高价值的软件,第二种方法可能会被欺骗,如果你的网络访问有限,或者你被堵在防火墙后面,这绝对是令人恼火的。
总的来说,与客户建立信任关系要容易得多!
检查部分密钥验证上的文章,它涵盖了以下要求:
许可证密钥必须易于输入。
我们必须能够黑名单(撤销)许可证密钥的情况下退款或购买与被盗的信用卡。
没有“打电话回家”来测试钥匙。虽然这种做法越来越普遍,但作为一个用户,我仍然不欣赏它,所以不会要求我的用户忍受它。
它不应该有可能为一个破解者来分解我们发布的应用程序,并产生一个工作“keygen”从它。这意味着我们的应用程序不会完全测试一个密钥进行验证。只有一些关键是要测试的。此外,应用程序的每个版本都应该测试密钥的不同部分,因此基于早期版本的假密钥将不能在我们的软件的后续版本上工作。
重要的是:合法用户不应该不小心输入一个无效的键,这个键看起来可以工作,但在未来的版本中由于排版错误而失败。
你可以使用(您需要从https://www.systemsoulsoftwares.com/下载创建安全许可证的桌面应用程序)在你的软件项目中很容易地使用和实现安全许可API
我意识到这个答案晚了10年。
一个好的软件许可密钥/序列号生成器不仅仅由一串随机字符或某个曲线生成器的值组成。使用有限的字母数字字母表,数据可以嵌入到包含各种有用信息的短字符串(例如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
上述许可服务器支持在线和离线验证模式。一个软件产品可能只从在线验证开始存在。当软件产品准备退役并且不再受支持时,它可以很容易地转移到离线验证,一旦用户升级到切换到离线验证的软件的最后一个版本,所有现有的密钥将继续工作。
在这里可以找到如何将上述许可证服务器集成到网站中以销售软件许可证和可安装的演示应用程序的现场演示(网站和演示应用程序都是开源的):
https://license-server-demo.cubiclesoft.com/
完全公开:我是许可证服务器和演示站点软件的作者。