如何为C#应用程序创建产品密钥?

时间:2009-01-17 09:06:23

标签: c# .net license-key

如何为C#应用程序创建产品密钥?

我需要创建每年更新的产品(或许可证)密钥。另外,我需要为试用版创建一个。

  

相关:

     

14 个答案:

答案 0 :(得分:80)

您可以执行类似创建包含要对应用程序进行身份验证的数据的记录的操作。这可能包括你想要的任何东西 - 例如程序功能启用,到期日期,用户名称(如果要将其绑定到用户)。然后使用一些加密算法用固定密钥加密或加密它。然后你只需在你的程序中验证它。分发许可证文件(在Windows上)的一种方法是将其作为更新注册表的文件提供(保存用户必须键入它)。

请注意虚假的安全感 - 迟早有人会简单地修改程序以跳过该检查,并分发修补后的版本。或者,他们会计算出一张钥匙,通过所有检查并分发,或者回溯时钟等。无论你制定计划有多复杂,你为此做的任何事情最终都会通过默默无闻来保证安全,而且他们总会能够做到这一点。即使他们不能有人会,并将分发黑客版本。即使您提供加密狗也是如此 - 如果有人愿意,他们也可以修补支票。对您的代码进行数字签名无济于事,他们可以删除该签名,或者将其签名。

通过使用防止程序在调试器中运行的技术等,您可以使问题复杂化,但即使这不是防弹。因此,您应该让一个诚实的用户不会忘记付费。另外要非常小心,你的计划不会对付费用户产生任何影响 - 最好是为你的付费用户提供一些剽窃副本而不是能够使用他们支付的费用。

另一种选择是进行在线检查 - 只需向用户提供唯一ID,并在线检查ID应具备的功能,并将其缓存一段时间。尽管如此,所有相同的警告都适用 - 人们可以绕过这样的事情。

还要考虑必须与忘记密钥等的用户打交道的支持费用

编辑:我只是想补充一点,不要在这方面投入太多时间,或者认为你的错综复杂的方案会有所不同和不可摧毁。它不会,也不会只要人们控制程序运行的硬件和操作系统。开发人员一直试图为此提出更复杂的方案,认为如果他们为它开发自己的系统,那么它将只为他们所知,因此“更安全”。但它确实是编程等同于尝试构建永动机。 : - )

答案 1 :(得分:15)

你信任谁?

我一直认为这个区域太重要了,不能信任第三方来管理应用程序的运行时安全性。一旦该组件针对一个应用程序被破解,它就会被破解以用于所有应用程序。在Discreet年前使用第三方许可证解决方案后,它在五分钟内发生了3ds Max ...好时光!

说真的,考虑自己动手来完全控制你的算法。如果这样做,请考虑使用密钥中的组件:

  • 许可证名称 - 您获得许可的客户名称(如果有)。对于管理公司部署很有用 - 让他们觉得在您提供的许可证信息中有一个“个性化”名称是特别的。
  • 许可证到期日期
  • 在同一许可下运行的用户数。这假设您有一种方法可以以服务器方式跟踪站点上的运行实例
  • 功能代码 - 允许您跨多个功能以及跨多个产品使用相同的许可系统。当然,如果一个产品被破解,它就会被破解。

然后对它们进行校验,并添加你想要的任何(可逆)加密,以使其更难破解。

要制作试用许可证密钥,只需设置上述值的值即可转换为“试用模式”。

由于现在这可能是您的应用程序/公司中最重要的代码,因此可以考虑将解密例程放在本机DLL文件中,而不是混淆,而是将P/Invoke放在其中。

我曾为之工作的几家公司采用了广泛的方法,取得了巨大的成功。或者也许产品不值得破解;)

答案 2 :(得分:11)

如果您询问可以输入的密钥,例如Windows产品密钥,则它们基于某些检查。如果您正在谈论必须复制粘贴的密钥,那么它们基于数字签名(私钥加密)。

简单的产品关键逻辑可以首先说明产品密钥由四个5位数组组成,如abcde-fghij-kljmo-pqrst,然后继续指定内部关系,如f + k + p应该等于a ,意思是2,3和4组的第一个数字应该总计为a。这意味着8xxxx-2xxxx-4xxxx-2xxxx有效,因此是8xxxx-1xxxx-0xxxx-7xxxx。当然,也会有其他关系,包括复杂的关系,如果第一组的第二个数字是奇数,那么最后一个组的最后一个数字也应该是奇数。通过这种方式,产品密钥的生成器和产品密钥的验证只会检查它是否符合所有规则。

加密通常是使用私钥(==数字签名)加密并转换为Base64的许可证信息字符串。公钥随应用程序一起分发。当Base64字符串到达​​时,它由公钥验证(==解密),如果发现有效,则激活产品。

答案 3 :(得分:9)

无论是微不足道还是难以破解,我都不确定它真的会带来很大的不同。

您的应用被破解的可能性与其有用性成正比,而不是产品密钥处理的强度。

就个人而言,我认为有两类用户。付钱的人。那些没有的人。即使是最微不足道的保护,这样做也可能会这样做。那些不这样做的人会等待裂缝或寻找其他地方。无论哪种方式,它都不会让你获得更多的钱。

答案 4 :(得分:6)

我必须承认我会做一些相当疯狂的事情。

  1. 找到CPU瓶颈并将其解压缩到P/Invokeable DLL文件。
  2. 作为后期构建操作,使用XOR加密DLL文件的一部分 加密密钥。
  3. 选择公钥/私钥方案,在DLL文件中包含公钥
  4. 安排以便解密产品密钥并对两者进行异或 两半一起导致DLL的加密密钥。
  5. 在DLL的DllMain代码中,禁用保护(PAGE_EXECUTE_READWRITE) 并用密钥解密。
  6. 制作一个LicenseCheck()方法,对其进行健全性检查 许可证密钥和参数,然后校验和整个DLL文件,抛出 许可证违规。哦,并做一些其他初始化 这里。
  7. 当他们找到并删除LicenseCheck时,会有什么乐趣 当DLL启动时segmentation faulting

答案 5 :(得分:5)

还有选项Microsoft Software Licensing and Protection(SLP)服务。读完之后我真的希望我能用它。

我非常喜欢根据许可证阻止部分代码的想法。热门的东西,最安全的.NET。即使你不使用它也很有趣!

  

Microsoft®软件许可和   保护(SLP)服务是一种   软件激活服务   使独立软件供应商   (ISV)采用灵活的许可   他们的客户条款。微软   SLP服务采用独特的方式   有助于保护的保护方法   您的申请和许可   允许您前往的信息   市场增长更快   客户合规。

注意:这是我发布带有敏感代码的产品的唯一方法(例如有价值的算法)。

答案 6 :(得分:5)

如果您想要一个简单的解决方案来创建和验证序列号,请尝试Ellipter。它使用椭圆曲线加密技术并具有“过期日期”功能,因此您可以创建试用版或时间限制注册密钥。

答案 7 :(得分:2)

产品密钥和激活的另一个便宜的低价工具是名为InstallKey的产品。看看www.lomacons.com

答案 8 :(得分:2)

一种简单的方法是使用Globally Unique Identifier(GUID)。 GUID通常存储为128位值,通常显示为32个十六进制数字,组以连字符分隔,例如{21EC2020-3AEA-4069-A2DD-08002B30309D}

System.Guid.NewGuid()的C#中使用以下代码。

getKey = System.Guid.NewGuid().ToString().Substring(0, 8).ToUpper(); //Will generate a random 8 digit hexadecimal string.

_key = Convert.ToString(Regex.Replace(getKey, ".{4}", "$0/")); // And use this to separate every four digits with a "/".

我希望它有所帮助。

答案 9 :(得分:1)

诀窍是拥有一个只有你知道的算法(这样才能在另一端解码)。

有一些简单的事情,例如“选择一个素数并为其添加一个幻数”

更复杂的选项,例如使用一组二进制数据的非对称加密(可能包括唯一标识符,版本号等),并将加密数据作为密钥分发。

也可能值得阅读this question的回复

答案 10 :(得分:1)

有一些工具和API可用。但是,我认为你不会免费找到一个;)

例如OLicense套件: http://www.olicense.de/index.php?lang=en

答案 11 :(得分:0)

您可以查看LicenseSpot。它提供:

  • 免费许可组件
  • 在线激活
  • 用于集成您的应用和在线商店的API
  • 序列号生成
  • 撤销许可
  • 订阅管理

答案 12 :(得分:0)

请检查此答案:https://stackoverflow.com/a/38598174/1275924

我们的想法是使用Cryptolens作为许可证服务器。这里是step-by-step example(在C#和VB.NET中)。我还在下面附上了一个用于密钥验证的代码段(在C#中):

var licenseKey = "GEBNC-WZZJD-VJIHG-GCMVD";
var RSAPubKey = "{enter the RSA Public key here}";

var auth = "{access token with permission to access the activate method}";
var result = Key.Activate(token: auth, parameters: new ActivateModel()
{
    Key = licenseKey,
    ProductId = 3349,
    Sign = true,
    MachineCode = Helpers.GetMachineCode()
});

if (result == null || result.Result == ResultType.Error ||
    !result.LicenseKey.HasValidSignature(RSAPubKey).IsValid())
{
    // an error occurred or the key is invalid or it cannot be activated
    // (eg. the limit of activated devices was achieved)
    Console.WriteLine("The license does not work.");
}
else
{
    // everything went fine if we are here!
    Console.WriteLine("The license is valid!");
}

Console.ReadLine();

答案 13 :(得分:0)

我要回顾一下@frankodwyer的好回答,并深入研究基于在线的许可。我是Keygen的创始人,这是为开发人员构建的许可REST API。

由于您提到要为您的应用程序提供2种“类型”的许可证,即“完整版”和“试用版”,我们可以简化并使用许可证中的功能许可证模型应用程序的特定功能(在这种情况下,有一个“完整”功能集和一个“试用版”功能集)。

首先,我们可以创建2个许可证类型(在Keygen中称为策略),每当用户注册帐户时,您都可以为他们生成“试用”许可证开始(“试用”许可实施我们的“试用”功能政策),您可以使用它在应用程序内进行各种检查,例如用户可以使用 Trial-Feature-A Trial-Feature-B

在此基础上,每当用户购买您的应用时(无论您使用的是PayPal,Stripe等),您都可以生成实施“完整”功能政策的许可并将其关联使用用户的帐户。现在,在您的应用程序中,您可以检查用户是否拥有可以执行 Pro-Feature-X Pro-Feature-Y 的“完整”许可证(通过执行类似{ {1}})。

我提到允许您的用户创建用户帐户 - 我的意思是什么?我已经在a couple other answers详细介绍了这一点,但我简要介绍了为什么我认为这是验证和识别用户的优秀方法:

  1. 用户帐户可让您将多个许可多台计算机单个用户相关联,让您深入了解客户的行为和提示他们进行“应用内购买”即购买“完整”版本(有点像移动应用)。
  2. 我们不应该要求我们的客户输入长许可证密钥,这些密钥既输入又难以跟踪,即很容易丢失。 (尝试在Twitter上搜索“丢失的许可证密钥”!)
  3. 客户习惯使用电子邮件/密码;我认为我们应该做人们习惯做的事情,以便我们能够提供良好的用户体验(UX)。
  4. 当然,如果你不想要来处理用户帐户而你希望你的用户输入许可证密钥,那就完全没问题了(和Keygen {{3} })。我只是提供另一种处理许可方面的方法,并希望为您的客户提供一个很好的用户体验。

    最后,由于您还提到要每年更新这些许可证,因此您可以在策略上设置持续时间,以便“完整”许可证在一年后过期,并且“试用”许可证最后说2周,要求您的用户在到期后购买新许可证。

    我可以深入挖掘,将机器与用户和类似的东西联系起来,但我想我会尽量避免这个答案,并专注于向用户授权功能。