How does string obfuscation in obfuscators work? - c#

I want to store a password in my app to encrypt the installation date and store it in some folder and perhaps also in the registry for a 30 day version of my app. I've been googling around a lot and most people suggest to store the installation date encrypted. I know whatever I do can still be cracked but I want it to be just reasonably hard to crack without calling home or stuff like that. I could, for example, have a const string store a password that is encrypted with a password stored in another const string and so on. This would make it a little bit more complicated. But since string obfuscation seems to be such a common task for obfuscators, I want to know if there is a better way to do it in case any of you have any idea how obfuscators usually obfuscate strings in code so I can repeat the procedure.
(I'm not going to purchase an obfuscator. I'm using the free version of dotfuscator which doesn't obfuscate strings and that's fine, but I wouldn't buy the paid version just to obfuscate a single string (in case the paid version obfuscate strings which I don't care).)
(And I still want to do the 30 day trial. I already read a lot about other options like making a free-light version and stuff like that. The 30 days version is the best option in my case.)

You will also need to consider what happens when users delete all your registry keys and reinstall your app to get another 30 days. The "best" option is to generate registration keys that have the date built into them. If they decide to reinstall your application they have to use a valid registration key and the only one they will have is the one with an older date.
Then you have to make sure they don't keep registering for new keys etc.
Anything more than this can be circumvented by decompiling and recompiling your application.
Building in a Date
I do something a little more complicated with identifying features of the users computer. I'll explain a simple way though. Keep in mind if they really wanted to decompile/recompile this won't work, but I'd say it falls under reasonably hard.
Generate a encryption key for your product.
Convert it into a byte[] so it isn't a String. (But also remember that "obscurity isn't security", but we aren't really trying to have an end all be all license scheme)
Take the users full name and concat it to the current date and concat that with the number of days their license is valid. You might end up with 01/10/2011 30 Andrew Finnell as the final string.
Encrypt that string and convert it to Base64.
This is your new license key. You can just have them cut and paste that into your application when they go to register.
If that key is too hard to manage you do something a little different. Basically you do what I said, but only take the first 16 hex'ed characters. You then store that with their name, date and number of days in the registry. When your application loads up you generate a new key with those stored values (name, date, days, etc) and compare the first 16 characters with whats stored in the registry.
Please keep in mind this is just a simple way to prevent users from sharing or taking advantage of your software. None of these are high security grade techniques and will result in key crackers if they really wanted to.

I agree with the earlier comment stating that anyone who has technical skills and a little bit of free time will defeat any encryption/misdirection scheme you put together if all of the moving parts are local to your application. Obfuscation tools (like Dotfuscator commercial SKU) do all include "string encryption" but this particular transform is considered to be the weakest of the lot (as compared to control flow obfuscation or overload induction renaming). Once a string is mangled, the "decryption" function is injected into the stack prior to the text being popped at runtime - anyone who wants to take the time to trace whatever process you undergo will soon have all of your tricks laid out in front of them (unless some of the tricks are remote). So, you mentioned that you were not trying to make anything bullet proof - just slow people down and deter opportunistic hacks - that being the case, then this type of technique is fine - you will deter "the opportunistic hacker" who will poke around for fun but is easily put-off (but that will be the extent of it).
Lastly, if your app was, by chance, a WP7 app - then the full commercial version of Dotfuscator is available at no charge (and does include string encryption, control flow, etc.) at www.preemptive.com/windowsphone7.html

Related

Can some hack my key license system by analysing my CLR DLLs?

My software (written in C#/.NET) have a simple key license system to activate certain resources. The way it works is: it creates a unique code based on the running computer's hardware, then mix this value with the client's activated licenses to create a password that will, on that specific computer, liberate access to the determinated resources. The key given to the client is a file with the password.
The way it verifies this is even simpler: the software calculates the expected password, and then matches with the password stored on the file. If it matches, the resources are liberated.
So, since the software itself calculates the correct password, I wonder if it's possible to someone take the software's DLLs and hack them to discover the calculation method.
Yes, and if you don't put effort in to obfuscating your code it is trivial to do.
There will always be ways to get around any protection you put in place, the only thing you can do is make it difficult enough that any attacker will get too frustrated and declare it is not worth his time to try and reverse engeneer your software. It is just a matter of how much time/money is it worth it to you to keep that one extra person from trying.
I wrote a fairly extensive answer to a similar question here that goes over what steps you can do to mitigate the problem, but there is nothing you can do to stop it.

Secure network traffic c#

I'm developing a program in C#.
It connects to the internet to see if this copy is valid.
Currently I'm just sending the licence key and getting a response (0 or 1) if the key is valid.
The problem is that some users just fake the data with some packet capturing tool and replay it.
So the application is very easy to crack. How can I prevent this?
Here is what I essentially want to prevent:
Network replay attacks
Authentication "emulators"
It should be impossible to find out what data is sent.
Maybe I should add the current time and then encrypt the packet ?
So it's always different ?
Attention: Please don't warn me that it's easy to crack the application itself by modifying it. I know that. This question is only about the network part.
If you use SSL or HTTPS then you don't have to worry about users cracking the data packets. This is easy because the libraries already exist and are easy to implement. With C# and IIs for example it is just a matter of installing the certs and changing a few configuration items. (Maybe a recompile with some slight code changes).
Assuming you actually want to prevent license abuse there are far better ways to do this. The "phone home" approach is easy to roll yourself, but as you've noticed it's full of holes.
Disclaimer: I work for a company that makes commercial tools to solve these license management and copy-protection issues. There are other similar products available from a variety of vendors.
This isn't that different from thinking about how to do setup for your application. Choices are roll your own or buy an existing 3rd party toolset. Rolling your own at first blush make seem cheaper, but that's perhaps only because you haven't really discovered all the true requirements to create something robust and reliable. The 3rd party tool vendor needs to charge for their products, but they've spent years discovering all the issues with particular problem set and have solved the problems. So that eliminates work for you and leaves you free to focus on where your application can add value.
The difference is if you get setup wrong your users will be irritated; if you get copy protection wrong your product will be pirated.
In any event, reducing license validation checking to a binary "either/or" condition is extremely easy to crack--doing that check over the net makes it 10 times easier (record playback attack). Modern approaches encrypt the executable and the license is contained in the key to decrypt it (this is an oversimplification since the actual methodology includes a lot more complexity to make it virtually impossible to get around). Only by having a valid license can the executable be decrypted on program load and run.
If you want to do it the way you've described, consider this:
Have the app use a predictable, changing value (such as a lookup from a table of random numbers coupled with some external value like time) to create some kind of hash. Have the server implement the same code. The server sends the hash to the app, which compares it to its own hash. If they match, the app is allowed to run. If they don't, it errors out. Since the hash is different on ever startup attempt, recording it over the network won't allow the user to get it to run the next time it tries to start.

Set expiry date for application

I want to set expire date for my C# Windows application.
It means that i.e after 30 days my app won't work. It is easy to do when we use system time, it means whenever my program starts i check today date and expire date.
The problem is if the user changes system time, my comparison won't be correct.
What other ways can this be done?
I would figure out a better way to get people to want to pay for the application, because fighting it can be a very futile effort, although you can make it more difficult with things like hardware dongles, phone home services, etc. If your price point is not high, customers won't want to put up with this.
May be keep a dummy .dll file in your app install folder, open it and keep the number of days and install date time. Every time application loads up, check it. .Dll files folks wont try to open and read. May be you can encrypt and store in it too. This could be very simple.
The first line of defense is to check with a server, checking out their system time so that the user cannot change his own. Also try to hide the start date (under some dummy name in the registry perhaps). These are pretty futile things though, smart users will be able to 'crack' this with minimal effort.
It's trivial to disassemble a C# application, so whatever you implement will be liable to easy circumvention. The best choice, in my opinion is to use third-party Licensing tools but do bear in mind that all can be circumvented, although they will be more robust.
How likely is your app to be pirated and is it worth the time/expense to do anything more than cursory checks?
It might be easier to simply have two versions of a DLL - one that must communicate with a server every X days to make sure it's still active and the "unlocked" (purchased) version.
As has been noted, determined users will find a way around whatever you do so you have to evaluate effort/return to determine how much attempting to secure your app is worth.
You could use a website that keeps the time to determine how long the program was installed.
You are probably going to get advice saying that it is not woth your effort.

How to obfuscate string constants?

We have an application which contains sensitive information and I'm trying my best to secure it. The sensitive information includes:
The main algorithm
The keys for an encryption/decryption algorithm
I've been looking at Obfuscating the code but it doesn't seem to help much as I can still decompile it. However, my biggest concern is that the keys used for encryption of serial numbers etc are clearly visible when you decompile the code, even when it's Obfuscated.
Can anyone suggest how I can secure these strings?
I realise one of the methods might be to remove any decryption from the application itself, while this may be possible in part, there are some features which have to use encryption/decryption - mainly to save a config file and to pass an 'authorisation' token to a DLL to perform a calculation.
There are ways to do what you want, but it isn't cheap and it isn't easy.
Is it worth it?
When looking at whether to protect software, we first have to answer a number of questions:
How likely is this to happen?
What is the value to someone else of your algorithm and data?
What is the cost to them of buying a license to use your software?
What is the cost to them of replicating your algorithm and data?
What is the cost to them of reverse engineering your algorithm and data?
What is the cost to you of protecting your algorithm and data?
If these produce a significant economic imperative to protect your algorithm/data then you should look into doing it. For instance if the value of the service and cost to customers are both high, but the cost of reverse engineering your code is much lower than the cost of developing it themselves, then people may attempt it.
So, this leads on to your question
How do you secure your algorithm and data?
Discouragement
Obfuscation
The option you suggest, obfuscating the code, messes with the economics above - it tries to significantly increase the cost to them (5 above) without increasing the cost to you (6) very much. The research by the Center for Encrypted Functionalities has done some interesting research on this. The problem is that as with DVD encryption it is doomed to failure if there is enough of a differential between 3, 4 and 5 then eventually someone will do it.
Detection
Another option might be a form of Steganography, which allows you to identify who decrypted your data and started distributing it. For instance, if you have 100 different float values as part of your data, and a 1bit error in the LSB of each of those values wouldn't cause a problem with your application, encode a unique (to each customer) identifier into those bits. The problem is, if someone has access to multiple copies of your application data, it would be obvious that it differs, making it easier to identify the hidden message.
Protection
SaaS - Software as a Service
A more secure option might be to provide the critical part of your software as a service, rather than include it in your application.
Conceptually, your application would collect up all of the data required to run your algorithm, package it up as a request to a server (controlled by you) in the cloud, your service would then calculate your results and pass it back to the client, which would display it.
This keeps all of your proprietary, confidential data and algorithms within a domain that you control completely, and removes any possibility of a client extracting either.
The obvious downside is that clients are tied into your service provision, are at the mercy of your servers and their internet connection. Unfortunately many people object to SaaS for exactly these reasons. On the plus side, they are always up to date with bug fixes, and your compute cluster is likely to be higher performance than the PC they are running the user interface on.
This would be a huge step to take though, and could have a huge cost 6 above, but is one of the few ways to keep your algorithm and data completely secure.
Software Protection Dongles
Although traditional Software Protection Dongles would protect from software piracy, they wouldn't protect against algorithms and data in your code being extracted.
Newer Code Porting dongles (such as SenseLock†) appear to be able to do what you want though. With these devices, you take code out of your application and port it to the secure dongle processor. As with SaaS, your application would bundle up the data, pass it to the dongle (probably a USB device attached to your computer) and read back the results.
Unlike SaaS, data bandwidth would be unlikely to be an issue, but performance of your application may be limited by the performance of your SDP.
† This was the first example I could find with a google search.
Trusted platform
Another option, which may become viable in the future is to use a Trusted Platform Module and Trusted Execution Technology to secure critical areas of the code. Whenever a customer installs your software, they would provide you with a fingerprint of their hardware and you would provide them with a unlock key for that specific system.
This key would would then allow the code to be decrypted and executed within the trusted environment, where the encrypted code and data would be inaccessible outside of the trusted platform. If anything at all about the trusted environment changed, it would invalidate the key and that functionality would be lost.
For the customer this has the advantage that their data stays local, and they don't need to buy a new dongle to improve performance, but it has the potential to create an ongoing support requirement and the likelihood that your customers would become frustrated with the hoops they had to jump through to use software they have bought and paid for - losing you good will.
Conclusion
What you want to do is not simple or cheap. It could require a big investment in software, infrastructure or both. You need to know that it is worth the investment before you start along this road.
All efforts will be futile if someone is motivated enough to break it. No one has managed to figure this out yet, even the biggest software companies.
I'm trying my best to secure it
I'm not saying this as a scathing criticism, just you need to be aware of what your trying to achieve is currently assumed to be impossible.
Obfuscation is security through obscurity, it does have some benefit as it will deter the most incompetent of hacker attempts, but largely it is wasted effort that could perhaps be better spent in other areas of development.
In answer to your original question, you are going to run into problems with intelligent compilers, they might automatically piece together the string into the compiled application removing some of your obfuscation efforts as a compilation optimisations. It would be hard to maintain as well, so I would reconsider your risk analysis model and perhaps resign yourself to the fact it can be cracked and if it has any value probably will be.
I recently read a very simple solution to OP.
Simple declare your constants as readonly string, not const string. That simple. Apparently const variables get written to a stack area in the binary but written as plain text whereas readonly strings get added to the constructor and written as a byte array instead of text.
I.e. If you search for it, you won't find it.
That was the question, right?
Using a custom algorithm (security through obscurity?), combined with storing the key inside the application, is simply not secure.
If you are storing some kind of a password, then you can use a one-way hashing function to ensure that decrypted data is unavailable anywhere in your code.
If you need to use a symmetric encryption algorithm, use a well known and tested one, like AES-256. But the key obviously cannot be stored inside your code.
[Edit]
Since you mentioned encryption of serial numbers, I believe you a one-way hashing function (like SHA-256) would really suit your needs better.
The idea is to hash your serial numbers during build time into their hashed representations, which cannot be reversed (SHA-256 is considered to be a pretty safe algorithm, compared to, say, MD5). During run time, you only need to apply the same hash function to the user input, and compare hashed values only. This way none of the actual serial numbers are available to the attacker.
#Tom Gullen have given a proper answer.
I merely got some suggestions on how you can make it harder for the users to access your keys and algorithm.
As for the algorithm: Do not compile your algorithm at compile time, but at runtime. To be able to do this you need to specify an interface which contains the methods for the algorithm. The interface is used to run it. Then add the source code for the algorithm as an encrypted string (embedded resource). Decrypt it at runtime and use CodeDom to compile it into a .NET class.
Keys: The usual way is to store spread parts of your key in different places in the application. Store each part as byte[] instead of string to make it a bit harder to find them.
If all your users have an internet connection: Fetch the algorithm source code and the keys using SSL instead.
Note that everything will be pieced together at runtime, anyone with a bit of more knowledge can inspect/debug your application to find everything.
i dont think you can easily obfuscate string constants, so if possible, dont use them :) you can use assembly resources instead, those you can encrypt however you want.
Depends what you're trying to do but can you use asymmetric encryption? That way you only need to store public keys with no need to obfuscate them.

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

How can I create a product key for my C# Application?
I need to create a product (or license) key that I update annually. Additionally I need to create one for trial versions.
Related:
How do I best obfuscate my C# product license verification code?
How do you protect your software from illegal distribution?
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 - e.g. 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).
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. 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!
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.
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. 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. This means that 8xxxx-2xxxx-4xxxx-2xxxx is valid, so is 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. 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.
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.
Find a CPU bottleneck and extract it to a P/Invokeable DLL file.
As a post build action, encrypt part of the DLL file with an XOR
encryption key.
Select a public/private key scheme, include public key in the DLL file
Arrange so that decrypting the product key and XORing the two
halves together results in the encryption key for the DLL.
In the DLL's DllMain code, disable protection (PAGE_EXECUTE_READWRITE)
and decrypt it with the key.
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. Oh, and do some other initialization
here.
When they find and remove the LicenseCheck, what fun will follow
when the DLL starts segmentation faulting.
There is the option Microsoft Software Licensing and Protection (SLP) Services as well. 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. 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 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.
Note: This is the only way I would release a product with sensitive code (such as a valuable algorithm).
If you want a simple solution just to create and verify serial numbers, try Ellipter. It uses elliptic curves cryptography and has an "Expiration Date" feature so you can create trial verisons or time-limited registration keys.
Another good inexpensive tool for product keys and activations is a product called InstallKey. Take a look at www.lomacons.com
One simple method is using a Globally Unique Identifier (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}.
Use the following code in C# by System.Guid.NewGuid().
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.
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. 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
Please check this answer: https://stackoverflow.com/a/38598174/1275924
The idea is to use Cryptolens as the license server. Here's a step-by-step example (in C# and VB.NET). I've also attached a code snippet for key verification below (in 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();
You can check LicenseSpot. It provides:
Free Licensing Component
Online Activation
API to integrate your app and online store
Serial number generation
Revoke licenses
Subscription Management
I'm going to piggyback a bit on #frankodwyer's great answer and dig a little deeper into online-based licensing. I'm the founder of Keygen, a licensing REST API built for developers.
Since you mentioned wanting 2 "types" of licenses for your application, i.e. 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).
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 e.g. can user use Trial-Feature-A and Trial-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. 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)).
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:
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" i.e. purchasing your "full" version (kind of like mobile apps).
We shouldn't require our customers to input long license keys, which are both tedious to input and hard to keep track of i.e. they get lost easily. (Try searching "lost license key" on Twitter!)
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).
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). 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.
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.

Categories