views:

906

answers:

6

Hi everyone,

I have a program, where the password to a database is set by a remote user. The program saves the username and password to an encrypted string in an xml file that otherwise should be human readable. Now, this works fine, I use the C# DES encryption with a key, and it get encrypted and decrypted. Now, the problem is that anyone can use reflector to see the key. Even with obfuscation, the key should be readily apparent. So, how does one deal with this? Now, I don't need this to be NSA secure, but I really would like to prevent anyone from peeking. Thanks.

EDIT: Thanks for all of the advice so far, information on this sort of thing is not very widespread, and I really appreciate general tips as well as specific answers.

+5  A: 

This is not really a problem about relector or not. It is about key management. DES and any other encryption scheme relies on keys being changed on a regular basis. Hard coding the key in code obviously violates this. To get around this, you should look into key management.

EDIT: To elaborate a bit: Depending on you setup, you could store the hashed passwords in the file system and rely on file system/user security or in a database an rely on the database rights.

Brian Rasmussen
could you be more specific in how one would go about handling this?
Steve
Please comment when down voting. Thanks.
Brian Rasmussen
+2  A: 

Unfortunately, there's never a 100% secure way of doing this. You can obfuscate the code, use unmanaged code for secret areas, but since your application is able to read the password again, so can any attacker who puts enough effort into it.

chris166
+8  A: 

Try using DPAPI (System.Security.ProtectedData class). This protects your encrypted data using the user or machine credentials. So only the user account that's accessing the data (user credentials) or a user that can log in to the machine (machine credentials) will be able to decrypt your data.

Joe
this approach works well for server side programs, but doesn't scale well for client side
Scott Weinstein
@Scott can you clarify
Remus Rusanu
This works especially well for client side code. It is harder to use DPAPI on a server side application (impersonation, service account access to profiles, etc.). On a client the user specifies their password on the first run of the app which is encrypted with their DPAPI key. The encrypted data is stored on their system so that only they (or an admin) can decrypt that data. When the user starts up the app again, DPAPI uses their keys to decrypt the password. You get the benefit of not storing a common encryption key in the assembly where it can be easily cracked.
Joe Kuemerle
+1  A: 

You shouldn't be storing the password encrypted at all. You should be storing it hashed instead, with a one way hash function. See:

http://www.codinghorror.com/blog/archives/000953.html

Alex319
Doesn't help in the OP's situation, where he needs the password to access an external resource (a database).
Joe
And how exactly would you present a *hash* in a connection string?
Remus Rusanu
+1  A: 

We had a similar situation. We ended up putting the key in a file and having the user enter some sort of password (or key using hashing) to be able to read the file. It was the pain of making the user enter more information, but it removes the key from the program.

SwDevMan81
+4  A: 

You shouldn't encrypt your password using a secret embedded in your application, that is the root of your troubles. No matter how strong your encryption is, the key is clearly exposed in your code.

You should ask your user for the credentials, store the db user/name and password in an ordinary configuration section in your app.config and rely on the DPAPI backed DpapiProtectedConfigurationProvider class to encrypt and decrypt the section for you, using either the machine keys or a user specific key. See the link I provided for a full example how to do this.

Remus Rusanu