encrypting a .Net application and assemblies

mmr picture mmr · Jan 30, 2009 · Viewed 8.8k times · Source

I have an encryption/copy protection question.

I'm writing an application for a company that uses a dongle. Please don't tell me that software protection is useless, or that I should just let it fly free into the air, or that any time I spend doing this is a waste; this isn't a philosophical question about the validity of software protection, more like a how-to.

As I understand it, the first step in cracking a dongle-protected piece of software is to remove all the calls to the dongle from the code (ie, patch the executable). Also as I understand it, I can create 'strong names' in .NET in order to protect the application and the assembly, as explained in this MSDN article.

Is strong naming enough to ensure that my application can't be easily patched? Or do I need to use some sort of encryption library? If I need to use a library, which one, or where can I get information about setting this up?

The next step, of course, is to put important algorithms on the dongle. I realize that these are just speed bumps to the dedicated cracker, but as our market share grows, the speed bump will help us get to the point where the sting of piracy is not so keenly felt (I hope).

Thanks!

Answer

Wim Coenen picture Wim Coenen · Jan 30, 2009

Assembly strong naming was never designed to protect against an attacker who is in control of the machine. From the msdn entry on delay signing:

The following example turns off verification for an assembly called myAssembly.dll.

sn –Vr myAssembly.dll

The design goal of strong names is to provide name uniqueness and to protect the user (not the publisher) against an attacker. If the user wants to disable all strong name checks, or maybe even strip out your signature and re-sign the assembly with his own key then there is technically speaking nothing to prevent him from doing so.

Simply loading your assemblies from an encrypted file is also not very useful because the decryption code itself cannot be encrypted and is therefore an easy target for reverse engineering.

As mentioned by other posters, what you are looking for is obfuscation. You probably already have such a tool: Visual Studio (at least 2005 and 2008) comes with the community edition of PreEmptive Solutions’ Dotfuscator. Microsoft also has its own "Software Licensing and Protection Services" product.

Obfuscation has some technical disadvantages however:

  • it may complicate your build process. You need an unobfuscated and an obfuscated build, because the latter is not debuggable.
  • I like to have an error dialog for unexpected exceptions where the user can click "copy details" and send me a mail with some technical information including the stack trace. With obfuscation however, you can forget about getting anything useful from Exception.StackTrace.
  • if your code makes use of reflection then there is a good chance that things will break in the obfuscated build, because internal type and member names are not preserved.