Licensing Your .NET Applications

Have you ever wanted to create a licensing scheme for a .NET application?  In some ways, this process is very easy... but in others, it's annoyingly complex.  I figured I'd write about a few different methods available, and discuss some of the issues this presents with .NET as a platform.

First, there is no single "right way" ... it all depends on the purpose of the licensing.  For example, is the licensing trying to reduce piracy?  Or, is it in place to remind the user or enforce licensing restrictions (such as concurrent users)?  Or a way to track support issues?   Another question to consider:  how much time and effort do you want to spend on integrating a licensing scheme?  How irritating is the licensing going to be to the end user?  (I've walked away from many shareware products as their licensing schemes were too irritating and/or limiting.  And let's face it: if you're the only producer of an application, there's no market for it to begin with.  So, the last thing you want to do is encourage your potential customers to use the competition.)

I'd imagine most people would want to curb piracy and perhaps raise awareness that the application is, indeed, licensed, but as any experienced .NET developer knows, that's not so easy.  The reason is: .NET IL code is very readable.  You can try this yourself by creating a simple form or console application and opening up the exe in Reflector or any other similar program.  This level of exposure makes it easy to discover any proprietary algorithms in the code, or gather enough information about the licensing scheme to circumvent it.  So while licensing may help address piracy/awareness issues, it does nothing to address code protection.

Some articles on the internet discuss some techniques for code protection, such as compiling the application using NGEN (native image generator).  I won't expound on this here, but I believe doing this is a bad idea as it really doesn't offer any IP protection (and, it imposes a number of limitations).

There are licensing classes built into the framework, however, these are mainly designed for design-time licensing.  Here, I'm mainly focused on runtime or end-user licensing and code protection. 

Because the IL is so readable, there are two things you can do to help protect your application.  The first: obfuscate.  Code obfuscation is all about misdirection -- an obfuscator will rename the symbols in code.  In theory, it's 100% as functional as the original code, but utterly confusing to read.  This mainly helps protect your algorithms -- lookiloos will have to be very motivated to make sense of the code.  You can try this out using Dotfuscator Community Edition, included in VS.  I say that the original code is identical "in theory" because there are some gotchas to be aware of, especially with ASPX applications.  When types are reflected, serialized, or otherwise loaded at runtime, you need to be careful about not renaming types that aren't fully participating in the rename.  For example, you generally can't rename a page class that's specified in the "inherits" attribute of the page directive, because the type can't be found at runtime.  Similarly, you need to be careful with serialization; while it's okay to serialize obfuscated code when the same code does the serialization and deserialization, be careful when compiling future versions as the type names may change (thus making the previously serialized objects non-serializable).

If you want to go the actual licensing route, there are any number of methods.  The first thing to decide:  how will activation be verified?  I don't recommend activation:  while it may offer great protection, customers hate it.  In addition, you're then forced to handle authentication for as long as you have customers.  The advantage, though, is clear: you remove verification code from the client, and of course can audit the activation attempts.   It's effective.

The way I recommend doing licensing: create an XML file that contains the details you wish to record, such as customer name, date of licensing, support expiration, or any other details you can think of.   It's not very useful to symmetrically encrypt or hash this data -- a user could simply look at the IL to get the encryption key or determine the hash algorithm (like SHA1) -- it's pretty standard stuff.

The best way is to use a digital signature.  Digital signatures use PKI to create a message digest using the private key of the owner (in this case, you).  The message digest is then verified using the corresponding public key.  The purpose of a message digest is not the encrypt the message contents, but rather ensure that the original content has not been modified.  Because it's virtually impossible to compute a valid digest with just the public key, it's near impossible to create a valid license without your private key.  The end result:  the plain text license file can't be modified.

The tricky part is: you still need to protect your code from modification and injection.  A malicious user could simply inject their own public key, and create a digest of their own license file.  If the application isn't secure enough, there'd be no way to stop this.  Alternatively, a hacker could simply change the IL to skip the validation altogether.  No doubt, there's a single method somewhere that ultimately returns a boolean indicating whether or not the license is valid: they could inject the equivalent of "return true;" to short circuit the algorithm.

Obfuscation can certainly make this more difficult.  The next step is to sprinkle the licensing throughout the application.  You need to balance maintainability, but by not having a single "IsLicenseValid()" method, you reduce the chances of an easy hack. 

Lastly, you need to digitally sign your code (not the license, although you do that, too) -- this is giving your assembly a strong name.  You can use the strong name utility (SN.exe) to generate a random private/public key pair.  Within the application properties, you can tell Visual Studio to sign the assembly with this key.  By doing this, the runtime will verify the application has not been modified before allowing the application to load (same idea as the digital signature above).   (In truth, there are ways to force the runtime to skirt these checks, but nothing is 100% foolproof.)

While a hacker could still modify your code, they're now forced to either skirt the .NET Framework checks, or building a new application altogether by piecing together your IL. 

The bottom line here is: if you follow these practices, it would be a serious pain to overcome a well protected application.  There may be some people who choose to do this anyway, but I think using obfuscation with strong named assemblies and digitally signed license files is both time effective at development time, and effective and protecting your property at run time.   In future posts, I'll blog about actually implementing these techniques.
Comments are closed

My Apps

Dark Skies Astrophotography Journal Vol 1 Explore The Moon
Mars Explorer Moons of Jupiter Messier Object Explorer
Brew Finder Earthquake Explorer Venus Explorer  

My Worldmap

Month List