繁体   English   中英

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

[英]How can I create a product key for my C# application?

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

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

相关:

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

但请注意错误的安全感 - 迟早有人会简单地修补您的程序以跳过该检查,并分发修补版本。 或者,他们会计算出一个通过所有检查并分发它的密钥,或者倒计时时钟等。 不管你的计划有多复杂,你为此所做的任何事情最终都将通过默默无闻而成为安全,他们将永远能够做到这一点。 即使他们不能,也有人会分发被黑的版本。 即使您提供加密狗,同样适用 - 如果有人愿意,他们也可以为此修补支票。 对您的代码进行数字签名无济于事,他们可以删除该签名,或辞职。

您可以通过使用防止程序在调试器等中运行的技术使问题复杂化,但即使这样也不是万无一失的。 所以你应该让它变得足够困难,以至于诚实的用户不会忘记付款。 还要非常小心,您的计划不会对付费用户造成干扰 - 最好有一些盗版副本,而不是让付费客户无法使用他们付费的内容。

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

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

编辑:我只想补充一点,不要在这方面投入太多时间,也不要认为您的复杂计划会以某种方式不同且无法破解。 只要人们控制您的程序运行所在的硬件和操作系统,它就不会,也不能。 开发人员一直试图为此提出更复杂的方案,认为如果他们为此开发自己的系统,那么只有他们自己知道,因此“更安全”。 但这确实是尝试构建永动机的编程等价物。 :-)

你信任谁?

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

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

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

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

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

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

我工作过的几家公司已经为此采用了通用的方法,并取得了巨大的成功。 或者也许这些产品不值得破解;)

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

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

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

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

您的应用程序被破解的可能性与它的实用性而非产品密钥处理的强度成正比。

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

我不得不承认我会做一些相当疯狂的事情。

  1. 找到 CPU 瓶颈并将其提取到P/Invokeable DLL 文件中。
  2. 作为构建后操作,使用 XOR 加密密钥加密部分 DLL 文件。
  3. 选择一个公钥/私钥方案,在DLL文件中包含公钥
  4. 安排以便解密产品密钥并将两半异或在一起产生 DLL 的加密密钥。
  5. 在 DLL 的 DllMain 代码中,禁用保护 (PAGE_EXECUTE_READWRITE) 并使用密钥对其进行解密。
  6. 制作一个 LicenseCheck() 方法,对许可证密钥和参数进行完整性检查,然后对整个 DLL 文件进行校验和,在其中任何一个上抛出许可证违规。 哦,在这里做一些其他的初始化。

当他们找到并删除 LicenseCheck 时,当 DLL 开始出现分段错误时,会有什么有趣的事情发生。

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

还有Microsoft 软件许可和保护(SLP) 服务选项。 在阅读了它之后,我真的希望我可以使用它。

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

Microsoft® 软件许可和保护 (SLP) 服务是一种软件激活服务,使独立软件供应商 (ISV) 能够为其客户采用灵活的许可条款。 Microsoft SLP 服务采用独特的保护方法,帮助保护您的应用程序和许可信息,使您能够在提高客户合规性的同时更快地进入市场。

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

一种简单的方法是使用全局唯一标识符(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 "/".

我希望它有帮助。

另一个用于产品密钥和激活的物美价廉的工具是名为 InstallKey 的产品。 看看www.lomacons.com

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

这个想法是使用Cryptolens作为许可证服务器。 这是一个分步示例(在 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();

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

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

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

也可能值得阅读对这个问题的回答

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

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

我将借助 @frankodwyer 的精彩回答,并深入研究基于在线的许可。 我是Keygen的创始人,这是一个为开发人员构建的许可 REST API。

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

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

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

我提到允许您的用户创建用户帐户——这是什么意思? 我已经在其他几个答案中详细介绍了这一点,但简要说明了为什么我认为这是验证和识别用户的绝佳方式:

  1. 用户帐户可让您将多个许可证多台机器单个用户相关联,让您深入了解客户的行为并提示他们进行“应用内购买”,即购买“完整”版本(类似于移动应用)。
  2. 我们不应该要求我们的客户输入很长的许可证密钥,这些密钥输入起来既乏味又难以跟踪,即它们很容易丢失。 (尝试在 Twitter 上搜索“丢失的许可证密钥”!)
  3. 客户习惯于使用电子邮件/密码 我认为我们应该做人们习惯做的事情,这样我们才能提供良好的用户体验(UX)。

当然,如果您不想处理用户帐户并且希望您的用户输入许可证密钥,那完全没问题(并且 Keygen 也支持这样做)。 我只是提供另一种处理许可方面的方法,并希望为您的客户提供良好的用户体验。

最后,因为您还提到您希望每年更新这些许可证,您可以在您的策略上设置一个持续时间,以便“完整”许可证将在一年后到期,而“试用”许可证会持续 2 周,要求您的用户购买新的许可证到期后。

我可以深入挖掘更多内容,将机器与用户相关联等等,但我想我会尽量保持这个答案简短,并专注于简单地向用户许可功能。

您可以检查LicenseSpot 它提供:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM