272

我目前正在开发一个产品(用 C# 开发),可以免费下载和安装,但版本非常有限。要访问所有功能,用户必须支付许可费并获得密钥。然后将该密钥输入应用程序以“解锁”完整版本。

由于使用这样的许可证密钥很常见,我想知道:

  1. 一般是怎么解决的?
  2. 如何生成密钥以及如何通过应用程序对其进行验证?
  3. 我怎样才能避免密钥在 Internet 上发布并被未支付许可证的其他人使用(密钥基本上不是“他们的”)。

我想我也应该以某种方式将密钥与应用程序的版本联系起来,这样就可以对功能版本中的新密钥收费。

在这种情况下我还应该考虑什么?

4

15 回答 15

137

警告:你不能阻止用户盗版,只能让诚实的用户更容易做正确的事。

假设您不想为每个用户进行特殊构建,那么:

  • 为自己生成产品的密钥
  • 取用户名
  • 使用(例如)SHA1 连接用户名和密钥和散列
  • 将 SHA1 哈希解压缩为字母数字字符串。这是个人用户的“产品密钥”
  • 在程序中,执行相同的哈希,并与产品密钥进行比较。如果相等,OK。

但是,我再说一遍:这不会阻止盗版


我最近读到这种方法在密码学上不是很可靠。但是这个解决方案已经很弱(因为软件本身必须在某处包含密钥),所以我认为这个发现不会使解决方案失效。

不过,我只是觉得我真的应该提到这一点;如果您打算从中获得其他东西,请小心。

于 2009-03-01T13:53:08.153 回答
124

生成许可证密钥的方法有很多,但真正安全的方法很少。很遗憾,因为对于公司而言,许可证密钥的价值几乎与真实现金相同。

理想情况下,您希望您的许可证密钥具有以下属性:

  1. 只有您的公司应该能够为您的产品生成许可证密钥,即使有人完全对您的产品进行逆向工程(这将发生,我从经验中说)。如果您认真控制许可,那么在您的软件中混淆算法或隐藏加密密钥确实是不可能的。如果您的产品成功,有人会在发布后的几天内制作密钥生成器。

  2. 许可证密钥应该只能在一台计算机上使用(或者至少您应该能够非常严格地控制它)

  3. 许可证密钥应该简短且易于通过电话键入或口述。您不希望每个客户都致电技术支持,因为他们不知道密钥是包含“l”还是“1”。您的支持部门会为此感谢您,并且您在这方面的成本会更低。

那么您如何解决这些挑战呢?

  1. 答案很简单,但在技术上具有挑战性:使用公钥加密的数字签名。您的许可证密钥实际上应该是签名的“文档”,包含一些有用的数据,并使用您公司的私钥签名。签名应该是许可证密钥的一部分。产品应使用相应的公钥验证许可证密钥。这样,即使有人可以完全访问您的产品逻辑,他们也无法生成许可证密钥,因为他们没有私钥。许可证密钥如下所示: BASE32(CONCAT(DATA, PRIVATE_KEY_ENCRYPTED(HASH(DATA)))) 这里最大的挑战是经典的公钥算法具有较大的签名大小。RSA512 具有 1024 位签名。您不希望您的许可证密钥包含数百个字符。最强大的方法之一是使用椭圆曲线密码学(仔细实施以避免现有专利)。对于相同的强度,ECC 密钥比 RSA 密钥短 6 倍。您可以使用 Schnorr 数字签名算法(专利于 2008 年到期 - 好 :) 等算法进一步减小签名大小

  2. 这可以通过产品激活来实现(Windows 就是一个很好的例子)。基本上,对于拥有有效许可证密钥的客户,您需要生成一些“激活数据”,这是一条将计算机的硬件 ID 作为签名数据嵌入的签名消息。这通常在 Internet 上完成,但只有一次:产品将许可证密钥和计算机硬件 ID 发送到激活服务器,激活服务器将签名消息发回(也可以简短易懂)电话)。从那一刻起,产品在启动时不再检查许可证密钥,而是检查激活数据,这需要计算机相同才能进行验证(否则,数据将不同,数字签名将无法验证)。

  3. 好吧,只需从您的键中消除冗余字符,如“1”、“l”、“0”、“o”。将许可证密钥字符串拆分为字符组。

于 2011-11-16T10:23:06.223 回答
81

简单的答案 - 无论您使用什么方案,它都可以被破解。

不要使用旨在防止黑客的系统来惩罚诚实的客户,因为黑客无论如何都会破解它。

与他们的电子邮件或类似内容相关联的简单散列代码可能就足够了。当人们需要重新安装或更新硬件时,基于硬件的 ID 总是成为一个问题。

关于这个问题的好帖子: http ://discuss.joelonsoftware.com/default.asp?biz.5.82298.34

于 2009-03-01T13:45:51.743 回答
61

生成密钥时,不要忘记将版本和内部版本号连接到您计算哈希值的字符串。这样一来,就没有一把钥匙可以解锁你曾经发布的所有东西。

当你在astalavista.box.sk中找到一些密钥或补丁后,你就会知道你成功地制作了一些流行到有人费心破解的东西。麾!

于 2009-03-01T14:06:30.273 回答
25

除了已经说过的......

由于中间语言问题,任何对 .NET 应用程序的使用本质上都是可破坏的。.NET 代码的简单反汇编将向任何人开放您的产品。那时他们可以轻松绕过您的许可代码。

您甚至不能再使用硬件值来创建密钥。虚拟机现在允许某人创建“许可”机器的映像并在他们选择的任何平台上运行它。

如果它是昂贵的软件,还有其他解决方案。如果不是这样,就让普通黑客很难做到。并接受最终会有未经许可的副本的事实。

如果您的产品很复杂,那么固有的支持问题将为您创造一些保护。

于 2009-03-01T17:56:06.680 回答
23

我是Cryptolens软件许可平台背后的开发人员之一,自 14 岁以来一直致力于许可系统。在这个答案中,我根据多年来获得的经验提供了一些技巧。

解决此问题的最佳方法是设置一个许可证密钥服务器,应用程序的每个实例都将调用该服务器以验证许可证密钥。

许可证密钥服务器的好处

许可证密钥服务器的优点是:

  1. 您始终可以立即更新或阻止许可证密钥。
  2. 每个许可证密钥都可以锁定到一定数量的机器上(这有助于防止用户在线发布许可证密钥供其他人使用)。

注意事项

虽然在线验证许可证可以让您更好地控制应用程序的每个实例,但互联网连接并不总是存在(尤其是如果您针对大型企业),因此我们需要另一种执行许可证密钥验证的方法。

解决方案是始终使用 RSA 或 ECC 等公钥密码系统对来自服务器的许可证密钥响应进行签名(如果您计划在嵌入式系统上运行,可能会更好)。您的应用程序应该只有公钥来验证许可证密钥响应。

因此,如果没有 Internet 连接,您可以改用之前的许可证密钥响应。确保在响应中存储日期机器标识符,并检查它不是太旧(例如,您允许用户最多离线 30 天等)并且许可证密钥响应属于正确的设备。

请注意,您应该始终检查许可证密钥响应的证书,即使您已连接到 Internet),以确保它在离开服务器后没有被更改(即使您的 API 到许可证密钥服务器使用 https)

保护秘密算法

大多数 .NET 应用程序都可以很容易地进行逆向工程(微软提供了一个反汇编程序来获取 IL 代码,一些商业产品甚至可以检索源代码,例如 C#)。当然,你总是可以混淆代码,但它永远不是 100% 安全的。

在大多数情况下,任何软件许可解决方案的目的都是帮助诚实的人诚实(即愿意付费的诚实用户不要忘记在试用期结束后付费等)。

但是,您可能仍然有一些您绝对不想泄露给公众的代码(例如,预测股票价格的算法等)。在这种情况下,唯一的方法是创建一个API 端点,您的应用程序将在每次执行该方法时调用该端点。它需要互联网连接,但它确保您的密码永远不会被客户端计算机执行。

执行

如果您不想自己实现所有内容,我建议您查看本教程Cryptolens的一部分)

于 2018-08-25T16:50:47.377 回答
11

我们用于生成许可证密钥的 C# / .NET 引擎现在作为开源维护:

https://github.com/appsoftware/.NET-Licence-Key-Generator

它基于“部分密钥验证”系统,这意味着只有您用来生成密钥的密钥子集必须编译到您的可分发文件中。您自己创建密钥,因此许可证实施对于您的软件是唯一的。

如上所述,如果您的代码可以反编译,那么绕过大多数许可系统相对容易。

于 2013-05-09T21:21:57.107 回答
6

我过去使用过Crypkey。它是众多可用的之一。

您只能使用任何许可方案在一定程度上保护软件。

于 2009-03-01T13:43:57.490 回答
6

不知道你想多详细

但我相信.net 可以访问硬盘序列号。

你可以让程序向你发送那个和一些 eles(比如 nic 的用户名和 mac 地址)

您根据该代码计算代码并将密钥通过电子邮件发送给他们。

他们将阻止他们在获得钥匙后更换机器。

于 2009-03-01T17:11:39.567 回答
4

完成您要求的所有事情的唯一方法是要求访问互联网并使用服务器进行验证。应用程序需要使用密钥登录服务器,然后您需要存储会话详细信息,例如 IP 地址。这将防止密钥在几台不同的机器上使用。这通常不太受应用程序用户的欢迎,除非这是一个非常昂贵和复杂的应用程序,否则不值得。

您可以只拥有应用程序的许可证密钥,然后检查客户端是否正确,但是很容易将此密钥分发给其他用户,并且可以使用反编译器生成新密钥。

于 2009-03-01T13:46:59.447 回答
4

我已经在我公司的软件 (C# .net) 上实现了基于 Internet 的一次性激活,该软件需要一个许可证密钥,该许可证密钥是指存储在服务器数据库中的许可证。该软件使用密钥访问服务器并获得许可信息,然后使用客户端计算机上的某些变量(CPUID 和其他不会经常更改的内容的组合)生成的 RSA 密钥在本地加密,然后将其存储在注册表。

它需要一些服务器端编码,但它对我们来说非常有效,当我们扩展到基于浏览器的软件时,我能够使用相同的系统。它还为您的销售人员提供有关软件使用人员、使用地点和时间的重要信息。任何仅在本地处理的许可系统都完全容易受到利用,尤其是在 .NET 中的反射。但是,就像其他人所说的那样,没有一个系统是完全安全的。

在我看来,如果您不使用基于 Web 的许可,那么保护软件根本没有任何意义。由于 DRM 可能引起的头痛,这对实际为此付出代价的用户是不公平的。

于 2013-05-12T01:43:16.733 回答
4

我坚信,只有基于公钥加密的许可系统才是正确的方法,因为您不必在源代码中包含生成许可所需的基本信息。

过去,我多次使用Treek 的许可库,因为它满足了这个要求并且提供了非常好的价格。它对最终用户和自身使用相同的许可证保护,直到现在还没有人破解它。您还可以在网站上找到避免盗版和破解的好技巧。

于 2015-01-08T07:01:24.257 回答
3

您可以使用免费的第三方解决方案为您处理此问题,例如 Quantum-Key.Net 它是免费的,通过它为您创建的网络销售页面通过贝宝处理付款,通过电子邮件发放密钥并将密钥使用锁定到特定计算机以防止盗版。

您还应该注意混淆/加密您的代码,否则可以使用 De4dot 和 .NetReflector 等软件轻松对其进行逆向工程。一个好的免费代码混淆器是 ConfuserEx,它使用起来快速、简单,并且比昂贵的替代品更有效。

您应该通过 De4Dot 和 .NetReflector 运行您完成的软件,对其进行逆向工程,看看如果他们做了同样的事情,破解者会看到什么,并确保您没有留下任何重要的代码暴露或不加掩饰。

您的软件仍然是可破解的,但对于临时破解者来说,推迟它们可能就足够了,这些简单的步骤也将防止您的代码被提取和重用。

https://quantum-key.net

如何使用ConfuserEx?

https://github.com/0xd4d/de4dot

https://www.red-gate.com/dynamic/products/dotnet-development/reflector/download

于 2018-04-10T20:20:11.453 回答
2

完全防止软件盗版是不可能的。您可以防止随意盗版,这就是他们所有的许可解决方案所做的。

如果您想防止重复使用许可证密钥,最好使用节点(机器)锁定许可。我已经为我的软件使用Cryptlex大约一年了。它也有一个免费计划,所以如果您不希望有太多客户,您可以免费使用它。

于 2016-01-31T19:04:50.940 回答
-4

I solved it by interfacing my program with a discord server, where it checks in a specific chat if the product key entered by the user exists and is still valid. In this way to receive a product key the user would be forced to hack discord and it is very difficult.

于 2021-02-18T19:06:10.010 回答