问题
I have a scenario that has been troubling me for years. If you have to connect to a database or other service (like a web service) using a username and password, where would be the safest place to store this information if you are connecting through a .NET assembly? I understand that you would have to encrypt the password, but then you run into a kind of chicken-egg problem -- fine -- you can encrypt it, but then where do you put the key?
In .NET, you can't hardcode the password because you can decompile .NET code.
I looked at using assembly based rights with Isolated Storage, but MS recommends against storing unencrypted secret items there because priveledged users can gain access, so again, we are moving the problem from point A to point B. So for examplem, a domain admin with no need to know about the information in a database would be able to get access because of the ability to be an admin on any workstation on the domain.
You can encrypt App.Config and Web.Config, but I believe priveledges users can access the keys.
I think you run into the same problem with DPAPI.
I had considered storing the passwords, encrypted in a remoted database and getting them through OS authentication, but our department prohibits the storage of passwords on database servers. I am pretty sure I am stuck and wanted confirmation.
回答1:
You don't want to store the password in the assembly, and reinventing the wheel only creates more trouble (and introduces more vulnerabilities) than it's worth. If you are using MS platform on both the database and web server, then the easiest way to handle this is use a trusted connection, and grant rights on the SQL server to the identity your application is using.
Second to that, I would just let DPAPI do its job to encrypt your connection settings.
回答2:
You can use the following methods of the .NET Framework to protect your data, they use the DPAPI internally to protect your data, and you can directly use them in C# or VB.NET without having to fiddle around with system DLL calls:
namespace System.Security.Cryptography
{
// Summary:
// Provides methods for protecting and unprotecting data. This class cannot
// be inherited.
public sealed class ProtectedData
{
public static byte[] Protect(byte[] userData,
byte[] optionalEntropy, DataProtectionScope scope);
public static byte[] Unprotect(byte[] encryptedData,
byte[] optionalEntropy, DataProtectionScope scope);
}
}
To use it, add the reference System.Security
to your project. I strongly recommend to use the byte array optionalEntropy
to add a SALT to your protected data (add some random values to the byte array which are unique for the data you intend to protect).
For scope
you can use DataProtectionScope.CurrentUser
, which will encrypt the data to protect with the current user's credentials.
In some scenarios, DataProtectionScope.LocalMachine
is useful as well. In this case, the protected data is associated with the machine context. With this setting any process running on the computer can unprotect data. It is usually used in server-specific applications that run on a server where untrusted users are not allowed access.
Use the Protect
method to encrypt the data, decrypt it with Unprotect
. You may store the returned byte array according to the requirements of your application (file, database, registry etc).
More about these methods can be found here at MSDN:
- Windows data protection - general information about DPAPI functionality,
- Protected data class - specification of the
ProtectedData
class, - Protect method - description about the usage of the
Protect
method
For code samples and in case you are interested in encrypting parts of the applications .config file, check this out:
- Encrypt passwords in config - article which explains how to encrypt parts of the web/app.config
I recommend you to use a SALT (i.e. by using the optionalEntropy
parameter) - it protects against rainbow table attacks.
There is one drawback of the DPAPI solution I'd like to mention: The key is generated based on your Windows credentials, which means whoever has access to your Windows credentials has possibly access to the protected data. A programm running under your account can access the protected data as well.
回答3:
This is good question and I've been looking for an answer myself. Problem I had was to keep db passwords secure in case server was hacked and individual files could be retrieved. One very interesting option I've found was that sections of web.config can be encrypted and decrypted automatically on the fly by .NET framework which would use Windows secure store to keep and retrieve encryption key for you. In my situation that was not available because my hosting provider was not supporting it but you may have a look at this option. Why I think it may work is that you can independently manage security of what users may access Windows secure store and significantly limit any potential breaches. A hacker who breaks into server might get a copy of your config files and all your assemblies but accessing decryption key would be another obstacle for him.
回答4:
There are a couple of options here.
- Store them in the config file encrypted
- Store them in an external file that is encrypted with a generated seed. Obfuscate the code that stores this base seed or store it in a c++ dll (harded to decompile).
来源:https://stackoverflow.com/questions/9609840/where-to-store-db-passwords-when-using-windows-net-or-asp-net-applications