What I would like to know is the definite approach to encrypting connection strings in a config file. Here are my questions:
Using machine-level encryption, can't anybody accessing my server write a little .Net program to read the contents of the connection strings?
If I am deploying my application to users machines in an enterprise environment, and the application has connection strings in a config file, how can I make sure only my application can decrypt it? The scenario is especially interesting in a ClickOnce deployment scenario. I've read about people storing the config unencrypted at the publisher server and encrypting at the machine level when the app is downloaded, installed and executed for the first time. This sounds so wrong to me - connection strings zipping unprotected through the wire, and sitting unprotected for a brief amount of time between download and application execution.
Can I have a public and private key, sign my app, encrypt the config file with a key, and when the user executes it, decryption would only be possible from the signed application?
Since I am using ClickOnce, I could have my encrypted sensitive information in the code or embedded, because ClickOnce won't detect a change unless the version # changes. So, if I need to recompile if I change my connection string, the point of an app.config is muted. What other approaches can I take, out-side using an config file, to achieve protection of the connection strings at the server, client and in between?
The encryption infrastructure is designed to protect the secrets of the current user from other users. It is not designed to protect the secrets of an application from the user using it. What you ask for is not encryption, is DRM, and you need to look into the DRM infrastructure for answers. I'm not aware of a managed library around the DRM API.
Good question actually,
You can not be sure noone will decrypt your connection string (or password). Of course you can encrypt it, but people will be able to decompile your application and see what encryption algrorithm you use and what key you use to decrypt your connection string/password. Maybe it's more like extreme scenario but it is possible (I was an evil cracker in student years :) ). So if you are afraid of such a scenario you have to protect your application, make it harder to disassemble. It's a theme for another discussion, but for example you can use Dotfuscator or other good obfuscator - it will make it harder for a cracker to understand what is going on inside your application.
So, one possible solution can be "encrypt connection string + use obfuscator", but, as I said, it will not give you 100% protection.
Storing secrets with a symmetric encryption is always problematic as long as you do not want to promt for a password or use another technical solution to decrypt your secret (like special hardware). When you have to store the complete key anywhere on the system there will be a way for other people to retrieve it.
I would definitely try to use the operating system's mechanism. When you work in a pure windows environment with MS-SQL you should use the integrated security instead of user/password. Other databases might have similar capabilities, too.
Another (weaker) option is to secure the cleartext file with the security settings of the operating system - only the user gets access to the file. However you and your users have to trust the administrators. In this case you should use symmetric encryption in addition. But see my first arguments - it will not be really secure.
Gustavo you may be able to implement this, (this is my plan for my application which is login based).
User inputs credentials in .Net app. Credentials get passed over to a .php server-side application which uses them to log in to the database and retrieve a key and pass it back to the .Net app. The key is then used on the hardcoded encrypted connection strings in the .Net app to allow full database access.