Thursday, May 08, 2008 9:08 AM rrobbins

ASP.NET Cryptography Insecurities

I've found a serious shortcoming in one of the security methods I've been using. I've inherited two projects in which social security numbers were stored in a database in an unencrypted format. For the web application I don't think the SQL Server 2005 built-in encryption methods are an option because the web hosting company is still using SQL Server 2000. Instead, I used the .NET Framework's built-in cryptography classes found in the System.Security.Cryptography namespace. I used the Rijndael (aka Advanced Encryption Standard (AES)) cipher in a custom assembly which I uploaded to the web server's bin directory without the source code. This encryption method relies on a 128 bit key and an initialization vector (IV) which are basically just byte arrays of 16 numbers.

The shortcoming with this security solution is that the 128 key and initialization vector (IV) can be obtained from the DLL by using Lutz Roeder's .NET Reflector. I was able to reverse engineer my DLL and easily found the keys you would need to decrypt the social security numbers. I then tried using Dotfuscator Community Edition 3.0 to see if it could obscure the keys but I was still able to find them although the variables were renamed a.a and a.b. I was still able to determine that RijndaelManaged was the encryption method and the byte arrays make it obvious that these are the keys (which are identical to the non-obfuscated version). I doubt that any obfuscator tool is going to touch a byte array so you really cannot have your keys in a DLL that can be reversed engineered.

The MSDN article on the RijndaelManaged.CreateEncryptor Method suggests that when you create a new instance of the RijndaelManaged class, it generates a new key and initialization vector (IV). However, this is not very clear and the sample code I've seen used byte arrays to specify the key and initialization vector.

Of course, if someone has a copy of your database and your application files then you are probably screwed anyway.

Filed under: , , , ,

Comments

# re: ASP.NET Cryptography Insecurities

Thursday, May 08, 2008 11:00 AM by Richard Gavel

Why not use an encrypted configuration section (using DPAPI) to store the key and initialization vector? Another option is to write some SQL Server functions to read/write the SSNs and decrypt/encrypt them (using an extended stored procedure to perform the operations).

# re: ASP.NET Cryptography Insecurities

Thursday, May 08, 2008 11:16 AM by Joe

> a serious shortcoming

Really you need to identify what threats you are trying to protect against, and implement a solution that includes one or more of physical security, authentication and authorization, and possibly encryption.

And as soon as you implement encryption, you have the problem of how to manage the keys.

DPAPI as suggested by Richard above is fine, but it means anyone who can log into the server can decrypt your data.  This may be OK if you've properly controlled access to your server.

Leave a Comment

(required) 
(required) 
(optional)
(required)