关于c#:如何生成和验证软件许可证密钥?

How to generate and validate a software license key?

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

因为使用像这样的许可证密钥,我想知道:

  • 通常如何解决?
  • 如何生成密钥以及如何通过应用程序验证密钥?
  • 我怎样才能避免让密钥在互联网上发布并被没有支付许可证的其他人使用(一个基本上不是"他们的"的密钥)。
  • 我想我也应该以某种方式将密钥绑定到应用程序的版本,这样就可以在功能版本中为新密钥收费。

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


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

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

    • 为自己生成产品的密钥
    • 取用户名
    • 使用(例如)SHA1连接用户名和密钥以及哈希
    • 将SHA1哈希解包为字母数字字符串。这是个人用户的"产品密钥"
    • 在程序中,执行相同的哈希,并与产品密钥进行比较。如果相等,那好吧。

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

    我最近读到这种方法在加密方面不是非常合理。但是这个解决方案已经很弱了(因为软件本身必须在某个地方包含密钥),所以我不认为这个发现会使解决方案无效。

    只是想我真的应该提到这个;如果你打算从中获得其他东西,请注意。


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

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

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

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

  • 许可证密钥应该简短,易于通过电话键入或指示。您不希望每个客户都致电技术支持,因为他们不了解密钥是否包含"l"或"1"。您的支持部门会为此感谢您,您将在此领域降低成本。

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

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

  • 这可以通过产品激活来实现(Windows就是一个很好的例子)。基本上,对于具有有效许可证密钥的客户,您需要生成一些"激活数据",这是一个嵌入计算机硬件ID作为签名数据的签名消息。这通常是通过互联网完成的,但仅限于ONCE:产品将许可证密钥和计算机硬件ID发送到激活服务器,激活服务器发送回签名的消息(也可以缩短并轻松指示电话)。从那一刻开始,产品在启动时不检查许可证密钥,而是激活数据,需要计算机才能进行验证(否则,DATA将不同,数字签名将无法验证)。请注意,激活数据检查不需要通过Internet进行验证:使用已嵌入产品中的公钥验证激活数据的数字签名就足够了。

  • 好吧,只需从键中删除多余的字符,如"1","l","0","o"。将许可证密钥字符串拆分为多个字符组。


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

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

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

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


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

    在你找到漂浮在astalavista.box.sk中的一些键或补丁后,你会知道你成功地创造了足够受欢迎的东西,以至于有人不愿意破解。麾!


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

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

    您甚至无法使用硬件值来创建密钥。虚拟机现在允许某人创建"许可"计算机的映像并在他们选择的任何平台上运行它。

    如果它是昂贵的软件,还有其他解决方案。如果不是这样,那么对于随意的黑客来说就足够了。并接受最终会有无牌副本的事实。

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


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

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

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

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


    我是Cryptolens软件许可平台背后的开发人员之一,自14岁起就开始从事许可系统工作。在这个答案中,我根据多年来积累的经验提供了一些技巧。

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

    许可证密钥服务器的好处

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

  • 您可以随时更新或阻止许可证密钥。
  • 每个许可证密钥都可以锁定到特定数量的计算机(这有助于防止用户在线发布许可证密钥以供其他人使用)。
  • 注意事项

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

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

    因此,如果没有互联网连接,您可以使用以前的许可证密钥响应。确保在响应中存储日期和机器标识符,并检查它是否太旧(例如,您允许用户最多脱机30天等)以及许可证密钥响应属于正确的设备。

    Note you should always check the certificate of license key response, even if you are connected to the internet), in order to ensure that it has not been changed since it left the server (this still has to be done even if your API to the license key server uses https)

    保护秘密算法

    大多数.NET应用程序都可以很容易地进行逆向工程(Microsoft提供了一个用于获取IL代码的反汇编程序,而某些商业产品甚至可以在例如C#中检索源代码)。当然,您总是可以对代码进行模糊处理,但它永远不会100%安全。

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

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

    履行

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


    我不知道你想要多精巧

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

    你可以让程序发送给你和eles的东西(比如nic的用户名和mac地址)

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

    他们在拥有钥匙后会让他们免于切换机器。


    我过去使用过Crypkey。这是许多可用的之一。

    您只能通过任何许可方案保护软件到一定程度。


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

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

    在我看来,如果你没有使用基于Web的许可,那么根本就没有保护软件的真正意义。由于DRM可能导致的头痛,对实际付费的用户来说,这是不公平的。


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

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


    就像其他一些人提到的那样,我是一个巨大的反对者,默认情况下对客户持敌对态度 - 这是许可行业臭名昭着的事情。因此,我将为您的问题扩展一个良好的解决方案,同时提供良好的客户用户体验。

    首先,您提到您拥有一个"有限"版本的软件,您正在尝试将客户转换为"升级"以获得其他功能。所以你要找的是产品的功能许可证,例如客户可以购买feature-X或feature-Y的许可证。

    我在构建Keygen时考虑到了这种类型的许可。 Keygen是一种许可REST API,允许您管理用户帐户,许可证以及跟踪机器使用/关联。

    我要做的是设置2种许可证类型(Keygen中的策略),其中一种是有限免费版本的基本策略,另一种是付费版本的策略。

    我不确定你用于支付的是什么,但我们假设你正在使用Stripe(现在很标准)提供webhooks。 Keygen也有webhooks(无论你是否使用它,所有这些仍然适用)。您可以使用来自双方的webhooks集成Keygen与您的支付提供商交谈(想想:customer.created - >为客户创建基本许可证,license.created - >为新许可证向客户收费)。

    因此,通过利用webhooks,我们可以为新客户自动创建许可证。那么应用程序本身的许可证验证呢?这可以通过多种方式完成,但最常用的方法是要求您的客户在输入字段中输入长许可证密钥,然后您可以对其进行验证;我认为这是处理应用程序中许可证验证的一种可怕方法。

    为什么我这么想?首先,您要求您的客户输入用于机器消耗的繁琐冗长的许可证密钥,其次要求您和您的客户跟踪所述冗长的许可证密钥。

    好的,那又有什么选择呢?我认为最好的选择是做一些所有客户习惯的事情:允许他们使用电子邮件/密码为您的产品创建帐户。然后,您可以将其所有许可证及其计算机与该帐户相关联。因此,现在他们只需使用凭据登录,而不是输入许可证密钥。

    这给你带来了什么好处?首先,它消除了您和您??的客户跟踪许可证密钥的需要,因为它们都在其用户帐户内部处理,最重要的是:您现在可以为您的客户提供自助服务许可证和机器激活!即,由于他们的所有许可证和机器都与其用户帐户相关联,因此当他们在未识别的计算机上启动您的应用程序时,您可以提示他们购买许可证。

    现在进入许可证验证:每当您的客户使用他们的电子邮件/密码登录您的应用程序时,您可以向他们的用户帐户查询他们拥有的许可证,以确定他们是否可以使用feature-X或feature-Y。由于您的应用程序现在是自助服务,因此您可以允许您的客户直接从您的应用程序中购买其他功能!

    因此,我们已经为我们的许可系统引入了大量自动化,我们可以授权个别功能(即有限版和完整版),我们为客户提供了一个很棒的用户体验,我们也减轻了其中一个最大的原因对于支持请求:许可证密钥恢复。

    无论如何,这很长,但希望它有助于某人!


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

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


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

    如果要防止重用许可证密钥,则最好使用节点(计算机)锁定许可。我一直在使用Cryptlex大约一年的时间用于我的软件。它也有一个免费的计划,所以如果你不期望太多的客户,你可以免费使用它。


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

    您还应该注意对代码进行模糊处理/加密,或者可以使用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