License keys are the defacto-standard as an anti-piracy measure. To be honest, this strikes me as (in)Security Through Obscurity, although I really have no idea how license keys are generated. What is a good (secure) example of license key generation? What cryptographic primitive (if any) are they using? Is it a message digest? If so, what data would they be hashing? What methods do developers employ to make it difficult for crackers to build their own key generators? How are key generators made?


当前回答

还有一些DRM行为将多个步骤合并到流程中。最著名的例子之一是Adobe验证其Creative Suite安装的方法之一。使用这里讨论的传统CD Key方法,然后调用Adobe的支持线。CD密钥将提供给Adobe代表,他们将返回用户使用的激活号码。

然而,尽管被分成了几个步骤,但这与正常过程中使用的破解方法相同。人们很快发现了用于创建与原始CD密钥进行检查的激活密钥的过程,并制作了包含这两个密钥的生成器。

然而,这种方法仍然作为一种没有互联网连接的用户验证产品的方式存在。展望未来,随着互联网接入变得无处不在,很容易看到这些方法将被淘汰。

其他回答

我对人们如何生成CD密钥没有任何经验,但是(假设你不想走在线激活的道路)这里有一些方法可以生成密钥:

Require that the number be divisible by (say) 17. Trivial to guess, if you have access to many keys, but the majority of potential strings will be invalid. Similar would be requiring that the checksum of the key match a known value. Require that the first half of the key, when concatenated with a known value, hashes down to the second half of the key. Better, but the program still contains all the information needed to generate keys as well as to validate them. Generate keys by encrypting (with a private key) a known value + nonce. This can be verified by decrypting using the corresponding public key and verifying the known value. The program now has enough information to verify the key without being able to generate keys.

这些漏洞仍然容易受到攻击:程序仍然存在,可以通过打补丁绕过检查。更聪明的方法可能是使用第三个方法的已知值加密部分程序,而不是将值存储在程序中。这样,在解密程序之前,你必须找到密钥的副本,但一旦解密,它仍然很容易被复制,并且有一个人拿着他们的合法副本,并使用它使其他人能够访问软件。

您可以在使用它的软件项目中非常容易地使用和实现安全许可API(您需要从https://www.systemsoulsoftwares.com/下载创建安全许可的桌面应用程序)。

Creates unique UID for client software based on System Hardware(CPU,Motherboard,Hard-drive) (UID acts as Private Key for that unique system) Allows to send Encrypted license string very easily to client system, It verifies license string and works on only that particular system This method allows software developers or company to store more information about software/developer/distributor services/features/client It gives control for locking and unlocked the client software features, saving time of developers for making more version for same software with changing features It take cares about trial version too for any number of days It secures the License timeline by Checking DateTime online during registration It unlocks all hardware information to developers It has all pre-build and custom function that developer can access at every process of licensing for making more complex secure code

当我最初写下这个答案时,假设这个问题是关于许可证密钥的“离线”验证。大多数其他答案都涉及在线验证,这明显更容易处理(大部分逻辑可以在服务器端完成)。

使用离线验证,最困难的事情是确保你可以生成大量唯一的许可密钥,并且仍然保持一个不容易被破坏的强大算法(例如一个简单的检查数字)。

我不是很精通数学,但我想到了一种方法,那就是使用一个数学函数来绘制图形

绘制的线可以有(如果使用足够精确的频率)数千个唯一点,因此可以通过在图上随机选择点并以某种方式编码值来生成键

例如,我们将绘制这张图,选择四个点并将其编码为字符串“0,-500;100,-300;200,-100;100,600”

我们将使用一个已知的固定密钥加密字符串(非常弱,但它是有目的的),然后通过Base32转换结果字节以生成最终密钥

然后应用程序可以反转这个过程(从base32到实数,解密,解码这些点),然后检查这些点是否在我们的秘密图上。

这是一个相当少的代码,将允许生成大量的唯一和有效的密钥

然而,它是非常安全的默默无闻。任何花时间分解代码的人都能够找到绘图函数和加密密钥,然后模拟密钥生成器,但它可能对于减缓随意的盗版非常有用。

如果您不是特别关心密钥的长度,那么使用公钥和私钥加密是一种行之有效的方法。

本质上有某种临时的和固定的签名。

例如: 0001 - 123456789

其中0001是您的临时签名,123456789是您的固定签名。

然后用你的私钥加密,得到你的CD密钥,就像这样: ABCDEF9876543210

然后在应用程序中分发公钥。公钥可用于解密CD密钥“ABCDEF9876543210”,然后验证其固定签名部分。

这可以防止某人猜测nonce 0002的CD密钥是什么,因为他们没有私钥。

唯一的主要缺点是,当使用1024位的私有/公共密钥时,您的CD密钥将非常长。您还需要选择一个足够长的nonce,这样您就不会加密少量的信息。

好的一面是,这种方法不需要“激活”就可以工作,你可以使用电子邮件地址或被许可方的名称作为临时标识。

我意识到这个答案晚了10年。

一个好的软件许可密钥/序列号生成器不仅仅由一串随机字符或某个曲线生成器的值组成。使用有限的字母数字字母表,数据可以嵌入到一个短字符串中(例如XXXX-XXXX-XXXX-XXXX),其中包括各种有用的信息,例如:

创建日期或license过期日期 产品ID、产品分类、主要版本号和次要版本号 自定义位,如硬件哈希 每个用户哈希校验和位(例如,用户输入他们的电子邮件地址和许可密钥,这两个信息都用于计算/验证哈希)。

然后对许可证密钥数据进行加密,然后使用有限的字母数字字母进行编码。对于在线验证,许可证服务器保存解密信息的秘密。对于脱机验证,解密秘密连同解密/验证代码一起包含在软件本身中。很明显,离线验证意味着软件不安全,无法防止有人输入密钥。

Probably the hardest part about creating a license key is figuring out how to cram as much data as possible into as few bytes as possible. Remember that users will be entering in their license keys by hand, so every bit counts and users don't want to type extremely long, complex strings in. 16 to 25 character license keys are the most common and balance how much data can be placed into a key vs. user tolerance for entering the key to unlock the software. Slicing up bytes into chunks of bits allows for more information to be included but does increase code complexity of both the generator and validator.

Encryption is a complex topic. In general, standard encryption algorithms like AES have block sizes that don't align with the goal of keeping license key lengths short. Therefore, most developers making their own license keys end up writing their own encryption algorithms (an activity which is frequently discouraged) or don't encrypt keys at all, which guarantees that someone will write a keygen. Suffice it to say that good encryption is hard to do right and a decent understanding of how Feistel networks and existing ciphers work are prerequisites.

验证密钥就是解码和解密字符串、验证散列/校验和、检查数据中的产品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/

完全公开:我是许可证服务器和演示站点软件的作者。