简体   繁体   English

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

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

How can I create a product key for my C# Application?如何为我的 C# 应用程序创建产品密钥?

I need to create a product (or license) key that I update annually.我需要创建一个每年更新的产品(或许可证)密钥。 Additionally I need to create one for trial versions.此外,我需要为试用版创建一个。

Related:相关:

You can do something like create a record which contains the data you want to authenticate to the application.您可以执行一些操作,例如创建一条记录,其中包含要向应用程序进行身份验证的数据。 This could include anything you want - eg program features to enable, expiry date, name of the user (if you want to bind it to a user).这可以包括您想要的任何内容 - 例如要启用的程序功能、到期日期、用户名(如果您想将其绑定到用户)。 Then encrypt that using some crypto algorithm with a fixed key or hash it.然后使用一些带有固定密钥的加密算法对其进行加密或对其进行散列。 Then you just verify it within your program.然后你只需在你的程序中验证它。 One way to distribute the license file (on windows) is to provide it as a file which updates the registry (saves the user having to type it).分发许可证文件(在 Windows 上)的一种方法是将其作为更新注册表的文件提供(无需用户输入)。

Beware of false sense of security though - sooner or later someone will simply patch your program to skip that check, and distribute the patched version.但请注意错误的安全感 - 迟早有人会简单地修补您的程序以跳过该检查,并分发修补版本。 Or, they will work out a key that passes all checks and distribute that, or backdate the clock, etc. It doesn't matter how convoluted you make your scheme, anything you do for this will ultimately be security through obscurity and they will always be able to this.或者,他们会计算出一个通过所有检查并分发它的密钥,或者倒计时时钟等。 不管你的计划有多复杂,你为此所做的任何事情最终都将通过默默无闻而成为安全,他们将永远能够做到这一点。 Even if they can't someone will, and will distribute the hacked version.即使他们不能,也有人会分发被黑的版本。 Same applies even if you supply a dongle - if someone wants to, they can patch out the check for that too.即使您提供加密狗,同样适用 - 如果有人愿意,他们也可以为此修补支票。 Digitally signing your code won't help, they can remove that signature, or resign it.对您的代码进行数字签名无济于事,他们可以删除该签名,或辞职。

You can complicate matters a bit by using techniques to prevent the program running in a debugger etc, but even this is not bullet proof.您可以通过使用防止程序在调试器等中运行的技术使问题复杂化,但即使这样也不是万无一失的。 So you should just make it difficult enough that an honest user will not forget to pay.所以你应该让它变得足够困难,以至于诚实的用户不会忘记付款。 Also be very careful that your scheme does not become obtrusive to paying users - it's better to have some ripped off copies than for your paying customers not to be able to use what they have paid for.还要非常小心,您的计划不会对付费用户造成干扰 - 最好有一些盗版副本,而不是让付费客户无法使用他们付费的内容。

Another option is to have an online check - just provide the user with a unique ID, and check online as to what capabilities that ID should have, and cache it for some period.另一种选择是进行在线检查——只需为用户提供一个唯一的 ID,然后在线检查该 ID 应该具有哪些功能,并将其缓存一段时间。 All the same caveats apply though - people can get round anything like this.尽管如此,所有相同的警告都适用 - 人们可以绕过这样的事情。

Consider also the support costs of having to deal with users who have forgotten their key, etc.还要考虑必须与忘记密钥等的用户打交道的支持成本。

edit: I just want to add, don't invest too much time in this or think that somehow your convoluted scheme will be different and uncrackable.编辑:我只想补充一点,不要在这方面投入太多时间,也不要认为您的复杂计划会以某种方式不同且无法破解。 It won't, and cannot be as long as people control the hardware and OS your program runs on.只要人们控制您的程序运行所在的硬件和操作系统,它就不会,也不能。 Developers have been trying to come up with ever more complex schemes for this, thinking that if they develop their own system for it then it will be known only to them and therefore 'more secure'.开发人员一直试图为此提出更复杂的方案,认为如果他们为此开发自己的系统,那么只有他们自己知道,因此“更安全”。 But it really is the programming equivalent of trying to build a perpetual motion machine.但这确实是尝试构建永动机的编程等价物。 :-) :-)

Who do you trust?你信任谁?

I've always considered this area too critical to trust a third party to manage the runtime security of your application.我一直认为这个领域太重要了,不能信任第三方来管理应用程序的运行时安全性。 Once that component is cracked for one application, it's cracked for all applications.一旦该组件为一个应用程序破解,它就会为所有应用程序破解。 It happened to Discreet in five minutes once they went with a third-party license solution for 3ds Max years ago... Good times!几年前,当Discreet使用3ds Max的第三方许可解决方案时,它在五分钟内就发生了……美好的时光!

Seriously, consider rolling your own for having complete control over your algorithm.说真的,考虑使用自己的算法来完全控制你的算法。 If you do, consider using components in your key along the lines of:如果您这样做,请考虑在您的密钥中使用以下组件:

  • License Name - the name of client (if any) you're licensing.许可证名称 - 您正在许可的客户端(如果有)的名称。 Useful for managing company deployments - make them feel special to have a "personalised" name in the license information you supply them.对管理公司部署很有用 - 让他们觉得在您提供给他们的许可证信息中有一个“个性化”的名字是特别的。
  • Date of license expiry许可证到期日期
  • Number of users to run under the same license.在同一许可证下运行的用户数。 This assumes you have a way of tracking running instances across a site, in a server-ish way这假设您有一种方法可以以服务器式的方式跟踪跨站点运行的实例
  • Feature codes - to let you use the same licensing system across multiple features, and across multiple products.功能代码 - 让您可以跨多个功能和多个产品使用相同的许可系统。 Of course if it's cracked for one product it's cracked for all.当然,如果它是针对一种产品破解的,那么它就会针对所有产品破解。

Then checksum the hell out of them and add whatever (reversable) encryption you want to it to make it harder to crack.然后对它们进行校验和并添加您想要的任何(可逆)加密以使其更难破解。

To make a trial license key, simply have set values for the above values that translate as "trial mode".要制作试用许可证密钥,只需将上述值设置为“试用模式”即可。

And since this is now probably the most important code in your application/company, on top of/instead of obfuscation consider putting the decrypt routines in a native DLL file and simply P/Invoke to it.由于这现在可​​能是您的应用程序/公司中最重要的代码,因此考虑将解密例程放在本机 DLL 文件中并简单地对其进行P/Invoke ,而不是混淆。

Several companies I've worked for have adopted generalised approaches for this with great success.我工作过的几家公司已经为此采用了通用的方法,并取得了巨大的成功。 Or maybe the products weren't worth cracking ;)或者也许这些产品不值得破解;)

If you are asking about the keys that you can type in, like Windows product keys, then they are based on some checks.如果您询问可以输入的密钥,例如 Windows 产品密钥,则它们基于某些检查。 If you are talking about the keys that you have to copy paste, then they are based on a digitial signature (private key encryption).如果您在谈论必须复制粘贴的密钥,那么它们基于数字签名(私钥加密)。

A simple product key logic could be to start with saying that the product key consists of four 5-digit groups, like abcde-fghij-kljmo-pqrst , and then go on to specify internal relationships like f+k+p should equal a, meaning the first digits of the 2, 3 and 4 group should total to a.一个简单的产品密钥逻辑可以首先说产品密钥由四个 5 位组组成,例如abcde-fghij-kljmo-pqrst ,然后继续指定内部关系,例如 f+k+p 应该等于 a,这意味着第 2、3 和 4 组的第一个数字应总计为 a。 This means that 8xxxx-2xxxx-4xxxx-2xxxx is valid, so is 8xxxx-1xxxx-0xxxx-7xxxx.这意味着 8xxxx-2xxxx-4xxxx-2xxxx 是有效的,8xxxx-1xxxx-0xxxx-7xxxx 也是如此。 Of course, there would be other relationships as well, including complex relations like, if the second digit of the first group is odd, then the last digit of the last group should be odd too.当然,也会有其他关系,包括复杂的关系,例如,如果第一组的第二位数字是奇数,那么最后一组的最后一位数字也应该是奇数。 This way there would be generators for product keys and verification of product keys would simply check if it matches all the rules.这样就有了产品密钥的生成器,并且产品密钥的验证将简单地检查它是否符合所有规则。

Encryption are normally the string of information about the license encrypted using a private key (== digitally signed) and converted to Base64 .加密通常是有关使用私钥(== 数字签名)加密并转换为Base64的许可证信息的字符串。 The public key is distributed with the application.公钥随应用程序一起分发。 When the Base64 string arrives, it is verified (==decrypted) by the public key and if found valid, the product is activated.当 Base64 字符串到达​​时,它通过公钥进行验证(==解密),如果发现有效,则产品被激活。

Whether it's trivial or hard to crack, I'm not sure that it really makes much of a difference.无论是微不足道的还是难以破解的,我都不确定它是否真的有很大的不同。

The likelihood of your app being cracked is far more proportional to its usefulness rather than the strength of the product key handling.您的应用程序被破解的可能性与它的实用性而非产品密钥处理的强度成正比。

Personally, I think there are two classes of user.我个人认为有两类用户。 Those who pay.付钱的人。 Those who don't.那些不这样做的人。 The ones that do will likely do so with even the most trivial protection.那些这样做的人可能会在最微不足道的保护下这样做。 Those who don't will wait for a crack or look elsewhere.那些不这样做的人会等待裂缝或寻找其他地方。 Either way, it won't get you any more money.无论哪种方式,它都不会让你赚更多的钱。

I have to admit I'd do something rather insane.我不得不承认我会做一些相当疯狂的事情。

  1. Find a CPU bottleneck and extract it to a P/Invokeable DLL file.找到 CPU 瓶颈并将其提取到P/Invokeable DLL 文件中。
  2. As a post build action, encrypt part of the DLL file with an XOR encryption key.作为构建后操作,使用 XOR 加密密钥加密部分 DLL 文件。
  3. Select a public/private key scheme, include public key in the DLL file选择一个公钥/私钥方案,在DLL文件中包含公钥
  4. Arrange so that decrypting the product key and XORing the two halves together results in the encryption key for the DLL.安排以便解密产品密钥并将两半异或在一起产生 DLL 的加密密钥。
  5. In the DLL's DllMain code, disable protection (PAGE_EXECUTE_READWRITE) and decrypt it with the key.在 DLL 的 DllMain 代码中,禁用保护 (PAGE_EXECUTE_READWRITE) 并使用密钥对其进行解密。
  6. Make a LicenseCheck() method that makes a sanity check of the license key and parameters, then checksums entire DLL file, throwing license violation on either.制作一个 LicenseCheck() 方法,对许可证密钥和参数进行完整性检查,然后对整个 DLL 文件进行校验和,在其中任何一个上抛出许可证违规。 Oh, and do some other initialization here.哦,在这里做一些其他的初始化。

When they find and remove the LicenseCheck, what fun will follow when the DLL starts segmentation faulting .当他们找到并删除 LicenseCheck 时,当 DLL 开始出现分段错误时,会有什么有趣的事情发生。

If you want a simple solution just to create and verify serial numbers, try Ellipter .如果您想要一个简单的解决方案来创建和验证序列号,请尝试Ellipter It uses elliptic curves cryptography and has an "Expiration Date" feature so you can create trial verisons or time-limited registration keys.它使用椭圆曲线加密并具有“到期日期”功能,因此您可以创建试用版或限时注册密钥。

There is the option Microsoft Software Licensing and Protection (SLP) Services as well.还有Microsoft 软件许可和保护(SLP) 服务选项。 After reading about it I really wish I could use it.在阅读了它之后,我真的希望我可以使用它。

I really like the idea of blocking parts of code based on the license.我真的很喜欢根据许可证阻止部分代码的想法。 Hot stuff, and the most secure for .NET.热门内容,最安全的 .NET。 Interesting read even if you don't use it!即使你不使用它也很有趣!

Microsoft® Software Licensing and Protection (SLP) Services is a software activation service that enables independent software vendors (ISVs) to adopt flexible licensing terms for their customers. Microsoft® 软件许可和保护 (SLP) 服务是一种软件激活服务,使独立软件供应商 (ISV) 能够为其客户采用灵活的许可条款。 Microsoft SLP Services employs a unique protection method that helps safeguard your application and licensing information allowing you to get to market faster while increasing customer compliance. Microsoft SLP 服务采用独特的保护方法,帮助保护您的应用程序和许可信息,使您能够在提高客户合规性的同时更快地进入市场。

Note: This is the only way I would release a product with sensitive code (such as a valuable algorithm).注意:这是我发布带有敏感代码(例如有价值的算法)的产品的唯一方式。

One simple method is using a Globally Unique Identifier (GUID).一种简单的方法是使用全局唯一标识符(GUID)。 GUIDs are usually stored as 128-bit values and are commonly displayed as 32 hexadecimal digits with groups separated by hyphens, such as {21EC2020-3AEA-4069-A2DD-08002B30309D} . GUID 通常存储为 128 位值,通常显示为 32 个十六进制数字,组由连字符分隔,例如{21EC2020-3AEA-4069-A2DD-08002B30309D}

Use the following code in C# by System.Guid.NewGuid() .通过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 "/".

I hope it helps.我希望它有帮助。

Another good inexpensive tool for product keys and activations is a product called InstallKey.另一个用于产品密钥和激活的物美价廉的工具是名为 InstallKey 的产品。 Take a look at www.lomacons.com看看www.lomacons.com

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

The idea is to use Cryptolens as the license server.这个想法是使用Cryptolens作为许可证服务器。 Here's a step-by-step example (in C# and VB.NET).这是一个分步示例(在 C# 和 VB.NET 中)。 I've also attached a code snippet for key verification below (in C#):我还在下面(在 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();

The trick is to have an algorithm that only you know (such that it could be decoded at the other end).诀窍是拥有一个只有你知道的算法(这样它就可以在另一端解码)。

There are simple things like, "Pick a prime number and add a magic number to it"有一些简单的事情,例如“选择一个质数并为其添加一个幻数”

More convoluted options such as using asymmetric encryption of a set of binary data (that could include a unique identifier, version numbers, etc) and distribute the encrypted data as the key.更复杂的选项,例如使用一组二进制数据(可能包括唯一标识符、版本号等)的非对称加密并将加密数据作为密钥分发。

Might also be worth reading the responses to this question as well也可能值得阅读对这个问题的回答

There are some tools and API's available for it.有一些工具和 API 可用于它。 However, I do not think you'll find one for free ;)但是,我认为您不会免费找到一个 ;)

There is for instance the OLicense suite: http://www.olicense.de/index.php?lang=en例如有 OLicense 套件: http ://www.olicense.de/index.php?lang=en

I'm going to piggyback a bit on @frankodwyer's great answer and dig a little deeper into online-based licensing.我将借助 @frankodwyer 的精彩回答,并深入研究基于在线的许可。 I'm the founder of Keygen , a licensing REST API built for developers.我是Keygen的创始人,这是一个为开发人员构建的许可 REST API。

Since you mentioned wanting 2 "types" of licenses for your application, ie a "full version" and a "trial version", we can simplify that and use a feature license model where you license specific features of your application (in this case, there's a "full" feature-set and a "trial" feature-set).由于您提到需要为您的应用程序提供 2 种“类型”的许可证,即“完整版”和“试用版”,我们可以简化它并使用功能许可证模型,您可以在其中许可应用程序的特定功能(在这种情况下,有一个“完整”功能集和一个“试用”功能集)。

To start off, we could create 2 license types (called policies in Keygen) and whenever a user registers an account you can generate a "trial" license for them to start out (the "trial" license implements our "trial" feature policy), which you can use to do various checks within the app eg can user use Trial-Feature-A and Trial-Feature-B .首先,我们可以创建 2 种许可证类型(在 Keygen 中称为策略),每当用户注册帐户时,您都可以为他们生成“试用”许可证以开始使用(“试用”许可证实现了我们的“试用”功能策略) ,您可以使用它在应用程序中进行各种检查,例如用户可以使用Trial-Feature-ATrial-Feature-B

And building on that, whenever a user purchases your app (whether you're using PayPal, Stripe, etc.), you can generate a license implementing the "full" feature policy and associate it with the user's account .在此基础上,每当用户购买您的应用程序(无论您使用 PayPal、Stripe 等)时,您都可以生成实施“完整”功能策略的许可证并将其与用户的帐户相关联。 Now within your app you can check if the user has a "full" license that can do Pro-Feature-X and Pro-Feature-Y (by doing something like user.HasLicenseFor(FEATURE_POLICY_ID) ).现在在您的应用程序中,您可以检查用户是否拥有可以执行Pro-Feature-XPro-Feature-Y的“完整”许可证(通过执行类似user.HasLicenseFor(FEATURE_POLICY_ID) )。

I mentioned allowing your users to create user accounts —what do I mean by that?我提到允许您的用户创建用户帐户——这是什么意思? I've gone into this in detail in a couple other answers , but a quick rundown as to why I think this is a superior way to authenticate and identify your users:我已经在其他几个答案中详细介绍了这一点,但简要说明了为什么我认为这是验证和识别用户的绝佳方式:

  1. User accounts let you associate multiple licenses and multiple machines to a single user , giving you insight into your customer's behavior and to prompt them for "in-app purchases" ie purchasing your "full" version (kind of like mobile apps).用户帐户可让您将多个许可证多台机器单个用户相关联,让您深入了解客户的行为并提示他们进行“应用内购买”,即购买“完整”版本(类似于移动应用)。
  2. We shouldn't require our customers to input long license keys, which are both tedious to input and hard to keep track of ie they get lost easily.我们不应该要求我们的客户输入很长的许可证密钥,这些密钥输入起来既乏味又难以跟踪,即它们很容易丢失。 (Try searching "lost license key" on Twitter!) (尝试在 Twitter 上搜索“丢失的许可证密钥”!)
  3. Customers are accustomed to using an email/password ;客户习惯于使用电子邮件/密码 I think we should do what people are used to doing so that we can provide a good user experience (UX).我认为我们应该做人们习惯做的事情,这样我们才能提供良好的用户体验(UX)。

Of course, if you don't want to handle user accounts and you want your users to input license keys, that's completely fine (and Keygen supports doing that as well ).当然,如果您不想处理用户帐户并且希望您的用户输入许可证密钥,那完全没问题(并且 Keygen 也支持这样做)。 I'm just offering another way to go about handling that aspect of licensing and hopefully provide a nice UX for your customers.我只是提供另一种处理许可方面的方法,并希望为您的客户提供良好的用户体验。

Finally since you also mentioned that you want to update these licenses annually, you can set a duration on your policies so that "full" licenses will expire after a year and "trial" licenses last say 2 weeks, requiring that your users purchase a new license after expiration.最后,因为您还提到您希望每年更新这些许可证,您可以在您的策略上设置一个持续时间,以便“完整”许可证将在一年后到期,而“试用”许可证会持续 2 周,要求您的用户购买新的许可证到期后。

I could dig in more, getting into associating machines with users and things like that, but I thought I'd try to keep this answer short and focus on simply licensing features to your users.我可以深入挖掘更多内容,将机器与用户相关联等等,但我想我会尽量保持这个答案简短,并专注于简单地向用户许可功能。

You can check LicenseSpot .您可以检查LicenseSpot It provides:它提供:

  • Free Licensing Component免费许可组件
  • Online Activation在线激活
  • API to integrate your app and online store用于集成您的应用程序和在线商店的 API
  • Serial number generation序列号生成
  • Revoke licenses吊销许可证
  • Subscription Management订阅管理

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

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