Question

I have researched on each element or system that I am willing to implement into a generic software licensing system for my soon-to-be apps (irrelevant, as this should work, or be usable on all of my applications).

I have created a DLL with my licensing class in it. It is as follows:


(1)

I have applied the InternalsVisibleTo() attribute main class (with child classes), which makes all of the internal classes, and their methods, which are declared Friend, visible to external assemblies with the sepcified PublicKey.

I have made the reference to the app name, and it's PublicKey. (Both the licensing, and the external assembly, are signed with the same key (.snk file)

(2)

All (where possible) members, properties etc. are delcared Friend or Private or just Dim...ed .

(3)

My licensing class has a String variable; declared:

Private Shared _Key As String = "H58N2-00V93"

This variable is the special password, if you will, of my DLL, and is required to access the methods in my DLL.

There is also a Public String variable (let's call it "AccessKey"), which should be initialized with the main class, like so:

Dim licDLL As New LicensingAssemblyName.LicensingMainClass With {.AccessKey="H58N2-00V93"}

(4)

Then, I have a Function (let's call it "CheckKey"), which checks whether the Public, initialized variable ("AccessKey" is equal to the pre-defined, Friend key ("_Key"), whereupon an exception will be thrown, if they are not equal - preventing method from continued/used.

(5)

At each first line of every Sub, Function etc., I have inserted a call to this function.


These are just the 'security' measures I've taken to prevent external assemblies from using my DLL in another app, to perhaps exploit the system or generate keys.

Now for the licensing measures.


(1)

I have a key generator (very basic), which generates codes upon a given format (Like: "#-$" for a number, a dash, followed by a letter.)

I have included an encryption class in this program, which uses Rijndaenal, and applies salt.

I have set the key generator to encrypt each separate key upon generation, then append it to a new line of a file, which we'll call "my_licenses.txt".

I use the same password for each one (obviously). It is quite long, and includes many different characters (if that makes ANY difference). I considered this to be a secure way since I didn't think ANYONE could decrypt a string without the password, until I was told by another programmer, who advised against using plain text encryption as a method to secure these keys. Please help me with this.

(2)

In my licensing DLL, I have a declaration:

Friend Shared Function IsKeyValid(ByVal KeyDB As String, ByVal Key As String) As Boolean

This function decrypts each key in the file (the specified database, using the same pass code used when encrypting them in the key generation program).

Then I do a For Each, Next loop to, determining whether the specified "Key" value equals any in the key 'database', "my_licenses.txt". But here's the catch.

I have an Function which returns a unique code for the computer it's running on (using hardware IDs etc.). This Function helps me protect against the use of the same key on multiple computers (unless I implement a system for allowing this, limited times) and is required as the last 5 characters of the "Key".

After checking, this Function returns a value of the result (True or False).


Finally (phew), each assembly (the licensing one, and any external ones which utilize it) are obfuscated -and likewise signed (all assemblies, with the same key (.snk) file)- by CodePlex's Confuser (A free, and highly recommended obfuscator for .NET).

I hope this hasn't been too long/not detailed enough/difficult to understand. (If so, tell me what you don't understand).

This is my first post/question of any kind, so be nice. Also thank you for reading.

I hope you can help.

And just to confirm, my question is this: Would this system be secure enough to protect against the average hacker?

P.S. I am only a beginner, so answers for a beginner would be especially appreciated ;)

*UPDATE: I have actually reduced the length of this question, and improved its understandability (believe it or not). So this is the best I can do.

Was it helpful?

Solution

That's an insane wall of text so you kind of lost me. And, to be honest I stopped reading seriously when I saw you had a hardcoded key inside the binary that you plan to distribute... But there are two questions you ought to ask yourself:

  1. Is your application likely to be so successful that there is sufficient demand for it so that people with the appropriate skillset will be inclined to reverse it and release a keygen and/or pirated version?

  2. And wouldn't your time be better spent adding cool features to the application instead of licensing code which does nothing to improve the application itself?

Don't get me wrong. I'm all for people getting paid for their work and I don't object to people licensing their software; as a matter of fact, one of the projects I worked on was a custom licensing engine which was tracking a little over 100,000 licenses last I checked. But make sure that if you decide to implement licensing that the effort you put into it doesn't exceed the effort you put into the actual software you're licensing.


With all that said, here's what I would do:

  • Generate a lot of licensing keys (using whatever format you want)
  • Hash those keys using something like SHA-256 or SHA-512.
  • Create an array (using whatever syntax is appropriate to your language of choice) that contains the key hashes.
  • Include the array inside your application.

With that setup, to verify a license, all you need to do is:

  • Hash the input using the same algorithm as before.
  • Iterate the array, comparing it with the result of the hash. If they match, the key is licensed. If they don't, continue.
  • If you get to the end of the table the key is not licensed.
  • Do not immediately exit the application if the key isn't licensed. Instead set a flag that prevents the use of important commands (e.g. "Save") or set a timer for 60 seconds plus a random number of to exit the application.

Compile and then digitally sign your application with Authenticode. Have the application itself validate the signature to try and discourage casual tampering.

If you are so inclined, you could even encrypt the hashes, although that is unlikely to help against the sort of attack that someone would mount against this scheme.

To be clear: this is not bulletproof (then again, no licensing mechanism is) and it's possible for someone sufficiently skilled to break it in a number of ways. But it's almost certainly going to be more than good enough for your project.

OTHER TIPS

Security doesn't have an absolute value, it has to be measured against the payoff. If your app is holding some nuclear codes I'd say go pay a specialized consultant for this. If you're storing grandma's secret recipes - you're good to go.

I read the whole post and it's still not clear what's the purpose of the hard-coded key or how do you manage the individual encryption keys for each license: encryption is not just about how strong an algorithm you use or how long your password is; it's also about how do you hide your passwords, how do you transmit them, what do you do in edge cases (interrupted connection, failed decryption etc) and many other things.

From the looks of it I'd say you're in the "good to go" category only because your app doesn't sound like a high-profile target to crack and you mostly want to deter the casual cracking attempt from a frustrated developer who doesn't like your licensing scheme (: and the obfuscation alone would deter most when it comes to reverse-engineering your code. I'm not familiar with your code to tell if there's any other, easier ways to bypass licensing, such as the popular method of copying the licensing file itself if it's not tied to the machine or user profile...

There are many workarounds online, but only hashing system described here or something based on public key cryptography can be secure enough to serve licensing.

I personally prefer and use commercial product: http://www.treekslicensinglibrary.com - Treek's Licensing Library. It's cheap, easy to setup and really secure as it uses previously meant public key cryptography to work with license.

Edit: To compare with hashes of serial numbers - this solution does not require to predefine accepted serial numbers. 1000 hashes in apps = 1000 licenses, for more you need to update your app. Public key cryptography based license systems do not have this disadvantage.

You can use a .NET Obfuscate application to secure it. All .NET application may decompile with .NET Reflector, so search in your browser the application to obfuscate .net application. This will work as i know, everyone that want to decompile your application will prevent by the obfuscate

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top