Signed XML

Posts   
 
    
Posts: 28
Joined: 17-Oct-2004
# Posted on: 26-May-2005 11:35:27   

I read a past article on this forum that talked about copy protection (http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=1652). Otis suggested using signed XML files for licensing.

I was wondering how/where one should store the public key. If someone wanted to crack your program they could easily generate a new key pair (private and public), sign the XML file, and replace the existing public key that your program uses. I thought about storing the public key as a constant string in XML format within the program. I could then check in random places for the expected public key and generate an error if it does not match. A mix of this with a strong name assembly (with random checks for the signature) should make it hard to crack. Any feedback would be greatly appreciated.

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 26-May-2005 14:04:50   

First off, is someone wants to crack your program they will. I think your best bet is to try an keep the honest people honest, in which case, what you are proposing will keep most people honest.

You should have a look at Xheo licensing. IMO, its a great licensing tool and provides many flavors and its cheap and saves a LOT of time.

jtgooding
User
Posts: 126
Joined: 26-Apr-2004
# Posted on: 26-May-2005 15:20:54   

I've had a good experience with XHEO as well.

John

hplloyd
User
Posts: 191
Joined: 29-Oct-2004
# Posted on: 26-May-2005 16:22:49   

Anyone used softwarekey.com licensing system.....

I have been reading up about it and it seems very comprehensive plus it comes with all the e-commerce stuff you would need to sell software online....

I would just like to know how it compares to XHEO if anyone has experience

Thanks

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39801
Joined: 17-Aug-2003
# Posted on: 26-May-2005 16:48:06   

Don't use XHeo, it took me 1 minute to find where they store the temp stuff in a demo installation. (I did an evaluation on them, before writing my own code, which is almost what Shannon explaines.

Oh, and don't display error messages if something isn't correct anymore. Set something valuable to null, so the app crashes.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 28
Joined: 17-Oct-2004
# Posted on: 26-May-2005 17:56:31   

Otis,

What do you recommend? How would you store the public key?

JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 27-May-2005 01:15:35   

I had a terrible experience with a product called ProtectionPlus. I will need to do something again on an upcoming project so I am very interested in this debate.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39801
Joined: 17-Aug-2003
# Posted on: 27-May-2005 11:54:37   

DotNetShannon wrote:

Otis,

What do you recommend? How would you store the public key?

Just in your assembly.

It works as follows: - encrypted with PRIVATE key is decryptable with PUBLIC key - encrypted with PUBLIC key is decryptable with PRIVATE key.

so reading your public key is not making them able to create a signed xml file which is then read by your app, as public key encrypted messages aren't decryptable with the public key.

So, they then have to alter the assembly, for example to store their own public key. This then violates the signing, i.e.: they have to remove the signatures using ildasm -> to file -> remove signatures -> ilasm -> go, or add their own.

In your code, you then have at a lot of random places checks on the signature of the assembly. If thats still the same as the one initially added to the assembly, i.e.: your public token is still the public token of the assembly.

Do this in obscure code, not with a string compare against a string read from a resource file, but with obscure byte compare code which uses several code snippets accros the assembly. Also don't use a single routine, use the check code everytime, no calls to a single routine.

As I said before: if the check fails, simply do something like _membervar = null; or _membervar.Collection.Clear(); this is a very obvious statement and not suspicious to a person using reflector. However because of the action, the app fails, perhaps 5 minutes later. it's then almost impossible to track down where the error originated. If you make it obvious where the error originated, you can track down where the stack trace originates and thus find the check code. Then you can find the rest of the check code and your app is cracked.

To make life more hard for them, also obfuscate code. Program for obfuscation, thus make all forms, all methods of a .exe project internal or private. When you do that, an obfuscator will produce very horrible to read code simple_smile (check the llblgen pro demo .exe assembly for example wink ).

It's then even harder to find the check code.

Though, if a cracker has too much time on his/her hands, it will be broken. Though: if your app is not something that has a very high 'coolness' factor and if it's hard to crack, no cracker will spend time on it.

Most copy protection breaches for professional software is done on the workplace: a co-worker has a license for app X and you want to use it too. You check a few things, if you can break it, cool, if you can't (i.e.: it takes 3 full days) you wont bother.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 28
Joined: 17-Oct-2004
# Posted on: 27-May-2005 15:15:44   

Otis,

I'm assuming you would not want to store your public key in a resource file since someone could easily generate a new resource file and your strong name checks would not apply? Storing the public key as XML in a constant string seems a bit quick and dirty.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39801
Joined: 17-Aug-2003
# Posted on: 27-May-2005 15:28:15   

DotNetShannon wrote:

Otis,

I'm assuming you would not want to store your public key in a resource file since someone could easily generate a new resource file and your strong name checks would not apply? Storing the public key as XML in a constant string seems a bit quick and dirty.

Why quick and dirty? It's a string you use in one particular method. So just define it there. Remember, this is copy protection code, the dirtier and harder to read, the better simple_smile

Frans Bouma | Lead developer LLBLGen Pro