There is a ton of material available for encryption in general, and I've been reading through it. But this question will not be about the actual encryption...it's how to secure the thing I use to do the encrypting.
I feel like the problem I am trying to solve is a simple one: my application needs to connect to a MySQL database on a website to fetch some information. That requires credentials to log into the database.
The application needs to have those credentials at the ready, so that means storing them securely, such as in app.config
. I can encrypt those items and then store them easily enough. I even took a stab at doing that, using aspnet_regiis -pef
to encrypt the section of the app.config where those were stored, but that seems to be a non-portable solution (e.g. worked on my dev PC, failed to decrypt on another computer). So if I am wrong about that, then let that be my question: how might that have failed me?
Otherwise, my question is this: how am I supposed to secure the key with which I encrypted the credentials? Is there an established best practice for making the key available to the application, while still protecting it in some way?
"You cant hide secrets"
Realistically you cannot secure anything you distribute. Your connection string is distributed in your app.config to potentially millions of customers, or at least can be copied millions of times. Your encryption algorithm may be very complex, but you must at least contain the decryption code in your .net application; which can be readily decompiled. All the hacker has to do is work out how/where your store your key. If they user doesn't supply it as part of the login process then you can't really secure the connection.
In the web application world we keep the connection string in web.config encrypted using the application pool service account credentials; only the app pool service account can read it. The user of the web site never gets access to the web.config, and if they did, the firewall between the DMZ and the database server would prevent them from attempting a connection. You lack any of these safeguards in a client-server application.
Ideally you would provide your end user with a SQL Server login based on their windows account credentials, or a username/password; you secure their SQL account rather than the ability to attempt to connect. This is reasonably secure in an intranet scenario, as SQL Server can delegate authentication lockout etc to the Windows Server allowing you to do three-strikes based login policies; but you cannot secure the attempt to connect - only the success of the connection attempt.