C# encryption in the age of reflector
Asked Answered
F

6

8

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.

Falstaffian answered 16/7, 2009 at 19:42 Comment(8)
You are asking a security question. You have identified the vulnerable resource -- the database. You have identified the vulnerability -- the lack of effective encryption on the password file. You have not identified the threat. It is dangerously counterproductive to try to figure out mitigations to the vulnerability without first identifying the threat! Who is threatening your resource, and how?Clypeus
Well, no one specifically, I would like to code my app to be secure and no what the best practices are.Falstaffian
The #1 best practice for coding secure applications is IDENTIFY THE THREATS. You cannot possibly be secure if you don't even know what threats you're securing the code against. I mean, suppose I asked you to design me a secure house. You'd probably start by making a list of threats to the occupants of the house as the first step, right?Clypeus
You should probably pick up a copy of Writing Secure Code. It will take you through the process of learning how to identify different kinds of threats and vulnerabilities, and what different techniques are for mitigating them. You might also want to read my article on why writing secure applications is like drinking Dr. Pepper: blogs.msdn.com/ericlippert/archive/2008/08/19/…Clypeus
"I mean, suppose I asked you to design me a secure house. You'd probably start by making a list of threats to the occupants of the house as the first step, right? ". No I'd start with the basics of bests practice (locks on the doors, ...). I don't disagree with your general point about security, but I think the OP's question about basic good practices is valid.Shorttempered
I'm not asking you to design me a house. Every house has locks on the doors by default. I'm asking you to specifically design me a secure house, and so the first question has to be "secure for who, against what threat?" Designing a house that is secure for the POTUS is a very different problem than designing a house that is secure for the warden of Alcatraz, is a very different problem than designing a house that is secure for a battered women's shelter. In designing secure systems you ALWAYS start with the threats to the resource.Clypeus
More specifically, the "best practice" for any form of encryption is: because encryption is a complex, fragile tool that is extremely good at mitigating a tiny number of vulnerabilities, and useless for everything else, the best practice for any system involving encryption is to first clearly identify what problem the encryption is intended to solve, and then have crypto experts work out precisely which algorithms solve that problem. So again, the best practice for crypto is always to work out the threats first.Clypeus
Never store passwords or keys in your program file...Hutton
S
8

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.

Shorttempered answered 16/7, 2009 at 19:50 Comment(2)
this approach works well for server side programs, but doesn't scale well for client sideNitrometer
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.Pufahl
P
5

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.

Pacesetter answered 16/7, 2009 at 19:47 Comment(1)
could you be more specific in how one would go about handling this?Falstaffian
S
4

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.

Soriano answered 16/7, 2009 at 20:2 Comment(0)
B
2

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.

Biometry answered 16/7, 2009 at 19:49 Comment(0)
I
1

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

Irrespective answered 16/7, 2009 at 19:50 Comment(2)
Doesn't help in the OP's situation, where he needs the password to access an external resource (a database).Shorttempered
And how exactly would you present a hash in a connection string?Soriano
C
1

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.

Corsica answered 16/7, 2009 at 19:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.