Where to store db passwords when using Windows .NE

2020-03-01 07:50发布

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 hard-code 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 privileged users can gain access, so again, we are moving the problem from point A to point B. So, for example, 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 the App. Config and Web.Config, but I believe privileged users can access the keys.

I think you run into the same problem with DPAPI.

I had considered storing the passwords, encrypted in a remote 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.

4条回答
聊天终结者
2楼-- · 2020-03-01 08:13

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 using 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:

For code samples and in case you are interested in encrypting parts of the application's .config file, check this out:

I recommend you to use a SALT (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 possibly has access to the protected data. A program running under your account can access the protected data as well.

查看更多
smile是对你的礼貌
3楼-- · 2020-03-01 08:13

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楼-- · 2020-03-01 08:16

There are a couple of options here.

  1. Store them in the config file encrypted
  2. 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).
查看更多
够拽才男人
5楼-- · 2020-03-01 08:19

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.

查看更多
登录 后发表回答