Sunday, January 13, 2008

Encryption is not safe in .Net, even it encrypts 128-bit blocks, if you do normal compilation!

With the release of .Net Reflector from Lutz Roeder, even dummy developer can de-compile your 10-years-effort application within seconds. It has become a open secret in the NET developers group and I think this is the main reason Microsoft releases some of the source code of framework libraries, although they often claim .NET is open architecture.

Reverse-engineering of your application is possible, when your source code is not obfuscated. For security purpose, developer maybe will use cryptographic services to encrypt user name & password and store it in clients'(users themselves) PC for reloading purpose. (So the application can log-in again for the same user without asking user name & password). This kind of information often could be a .ini/.config/.xml or any other ASCII file.

Cryptographic services help your client stores private and confidential information from others. The higher the bits used to perform encryption/decryption, the more difficult the hackers can hack your code. But now the problem is not coming from the algorithm but the .NET itself, if you are writing normal codes without obfuscating it.

Let's have a sample from MSDN using RijndaelManaged Class:
(The demo here is to urge the developers to tighten-up the security, not to encourage hackers!)

2) Browse to the .NET application you wish to de-compile. Drag-and-drop it to the .Net Reflector. (Sample provided; remove the "Config.ini" file to re-generate)

3) Browse to the default namespace. You might ask: How do you know it is default namespace? Normally it is same name with the application. If not sure, just browse one-by-one, since you can de-compile all the them :-D

4) Browse to default class. You might ask again: How do you know it is default class? Same answer with step (3).

Browse to default form/module. You might ask for 3rd time: How do you know it is default form/module? For C#, normally developers will name it as frmMain/frmMDI/frmLogin. In VB .Net, the entry point should be modmain module. Else, just follow step (3) :-)

5) Until here, maybe you have no choice but to look into all the possible methods (sometimes you can find the possible method like : frmLogin_Load, btnLogin_Click, etc). Click the methods to check the disassembler in the right pane.

Now you can see the user name & password are decrypted, before they are used to validate/compare with the user input.

6) Remember the configuration file in the form constructor. It's useful later to find out the where the encrypted information stored.

7) Click on the any method on the disassembler pane to drill down. If it requires additional assembly, message box will be prompted. Just click OK.

8) Again, Click on the method on the disassembler. You can find the decryption method. It uses Rijndael algorithm.

9) Oh, my God! It comes with IV and key, embeded in the application.

10) Copy decryption method, IV, key and build a simple console application. (Sample provided)

11) Pass-in the encrypted string to the console application built previously.
Done! Now you are a hacker! Oops, sorry, I meant you must tighten-up you source code compilation for security purpose.

p/s: Even in java, there're tons of de-compiler tools available. It's not surprise, since .NET is modeling from Java.


Kris Vandermotten said...

The problem is not .NET or the Rijndael encryption. The problem is that you store a key in your program. Relying on security by obscurity has always been a bad idea. Or do you think a hacker can't disassemble a native program?

Think about your requirements. You want to keep the password stored in the file confidential, such that only the user who knows the password can read it back, right?

Have a look at System.IO.File.Encrypt() and File.Decrypt(). Of you go. The contents of the file is perfectly safe from everyone, except for the user who typed it in in the first place. And there are no secrets in code, every hacker is welcome to see the source.

Obviously, more advanced schemes exist as well, but the above meets the needs and is very simple.

In fact, it meets the needs better than your original program. In your version, everyone with access to the file and the program can use the program to connect to the password protected database! With File.Encrypt, only the user who typed the password can do this.

You might want to go one step further in restating your requirements. Why do want to use a password anyway? Use SQL Server Windows authentication with integrated security. No password needed to connect in that case.

gary said...

Hi kris, thanks for your comemnt. I am in the midst of preparation of asymmetric cryptography, you gave me a alternative way to encryption.