Credential Storage Best Practices

I am writing a Windows service and must fulfill authenticated web requests. The service will not operate under the credentials used for the request; this means that I need to somehow save the credentials for the request.

What are the best practices here? Credentials will need to be stored in App.config (or equivalent); I would prefer that the password does not hang in the plain text. Since passwords change frequently, creating or otherwise baking in a password for a binary file is not an option.

The same question applies to Powershell. I need to make authenticated requests, but I do not want the script to contain the credentials used for the requests in text format.

+4
source share
3 answers

I can not take responsibility for the answer: But here is a blog post called "Password Encryption in .NET App Config" with the full code.

http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx

+6
source

I always refer to Keith Brown's “.NET Developer's Guide for Windows Security” for such things.

The full text is online http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook.HomePage

The specific section that you want (while keeping secrets) is at http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/HowToStoreSecretsOnAMachine.html

+2
source

Option number 1 . Encrypt the sections in the App.config file for the Web.config file using the ProtectSection() method. This is designed to work in Web and Desktop applications, as well as in web farms that rely on the replication of Web.config files with encrypted partitions.

In the depths of the MSDN tutorials that use the RSA provider:

Example:

 static public void ProtectSection() { // Get the current configuration file. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.None); // Get the section. UrlsSection section = (UrlsSection)config.GetSection("MyUrls"); // Protect (encrypt)the section. section.SectionInformation.ProtectSection( "RsaProtectedConfigurationProvider"); // Save the encrypted section. section.SectionInformation.ForceSave = true; config.Save(ConfigurationSaveMode.Full); // Display decrypted configuration // section. Note, the system // uses the Rsa provider to decrypt // the section transparently. string sectionXml = section.SectionInformation.GetRawXml(); Console.WriteLine("Decrypted section:"); Console.WriteLine(sectionXml); } 

An older approach using a DPAPI provider:

To encrypt:

 aspnet_regiis -pe "connectionStrings" -app "/SampleApplication" -prov "RsaProtectedConfigurationProvider" 

To decrypt:

 aspnet_regiis -pd "connectionStrings" -app "/SampleApplication" 

Unencrypted section:

 <configuration> <connectionStrings> <add name="SampleSqlServer" connectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;" /> </connectionStrings> </configuration> 

Encrypted section:

 <configuration> <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider"> <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <KeyName>RSA Key</KeyName> </KeyInfo> <CipherData> <CipherValue>RXO/zmmy3sR0iOJoF4ooxkFxwelVYpT0riwP2mYpR3FU+r6BPfvsqb384pohivkyNY7Dm4lPgR2bE9F7k6TblLVJFvnQu7p7d/yjnhzgHwWKMqb0M0t0Y8DOwogkDDXFxs1UxIhtknc+2a7UGtGh6Di3N572qxdfmGfQc7ZbwNE= </CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>KMNKBuV9nOid8pUvdNLY5I8R7BaEGncjkwYgshW8ClKjrXSM7zeIRmAy/cTaniu8Rfk92KVkEK83+UlQd+GQ6pycO3eM8DTM5kCyLcEiJa5XUAQv4KITBNBN6fBXsWrGuEyUDWZYm6Eijl8DqRDb11i+StkBLlHPyyhbnCAsXdz5CaqVuG0obEy2xmnGQ6G3Mzr74j4ifxnyvRq7levA2sBR4lhE5M80Cd5yKEJktcPWZYM99TmyO3KYjtmRW/Ws/XO3z9z1b1KohE5Ok/YX1YV0+Uk4/yuZo0Bjk+rErG505YMfRVtxSJ4ee418ZMfp4vOaqzKrSkHPie3zIR7SuVUeYPFZbcV65BKCUlT4EtPLgi8CHu8bMBQkdWxOnQEIBeY+TerAee/SiBCrA8M/n9bpLlRJkUb+URiGLoaj+XHym//fmCclAcveKlba6vKrcbqhEjsnY2F522yaTHcc1+wXUWqif7rSIPhc0+MT1hB1SZjd8dmPgtZUyzcL51DoChy+hZ4vLzE= </CipherValue> </CipherData> </EncryptedData> </connectionStrings> </configuration> / yjnhzgHwWKMqb0M0t0Y8DOwogkDDXFxs1UxIhtknc + 2a7UGtGh6Di3N572qxdfmGfQc7ZbwNE = <configuration> <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider"> <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <KeyName>RSA Key</KeyName> </KeyInfo> <CipherData> <CipherValue>RXO/zmmy3sR0iOJoF4ooxkFxwelVYpT0riwP2mYpR3FU+r6BPfvsqb384pohivkyNY7Dm4lPgR2bE9F7k6TblLVJFvnQu7p7d/yjnhzgHwWKMqb0M0t0Y8DOwogkDDXFxs1UxIhtknc+2a7UGtGh6Di3N572qxdfmGfQc7ZbwNE= </CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>KMNKBuV9nOid8pUvdNLY5I8R7BaEGncjkwYgshW8ClKjrXSM7zeIRmAy/cTaniu8Rfk92KVkEK83+UlQd+GQ6pycO3eM8DTM5kCyLcEiJa5XUAQv4KITBNBN6fBXsWrGuEyUDWZYm6Eijl8DqRDb11i+StkBLlHPyyhbnCAsXdz5CaqVuG0obEy2xmnGQ6G3Mzr74j4ifxnyvRq7levA2sBR4lhE5M80Cd5yKEJktcPWZYM99TmyO3KYjtmRW/Ws/XO3z9z1b1KohE5Ok/YX1YV0+Uk4/yuZo0Bjk+rErG505YMfRVtxSJ4ee418ZMfp4vOaqzKrSkHPie3zIR7SuVUeYPFZbcV65BKCUlT4EtPLgi8CHu8bMBQkdWxOnQEIBeY+TerAee/SiBCrA8M/n9bpLlRJkUb+URiGLoaj+XHym//fmCclAcveKlba6vKrcbqhEjsnY2F522yaTHcc1+wXUWqif7rSIPhc0+MT1hB1SZjd8dmPgtZUyzcL51DoChy+hZ4vLzE= </CipherValue> </CipherData> </EncryptedData> </connectionStrings> </configuration> + GQ6pycO3eM8DTM5kCyLcEiJa5XUAQv4KITBNBN6fBXsWrGuEyUDWZYm6Eijl8DqRDb11i + StkBLlHPyyhbnCAsXdz5CaqVuG0obEy2xmnGQ6G3Mzr74j4ifxnyvRq7levA2sBR4lhE5M80Cd5yKEJktcPWZYM99TmyO3KYjtmRW / Ws / XO3z9z1b1KohE5Ok / YX1YV0 + Uk4 / yuZo0Bjk + rErG505YMfRVtxSJ4ee418ZMfp4vOaqzKrSkHPie3zIR7SuVUeYPFZbcV65BKCUlT4EtPLgi8CHu8bMBQkdWxOnQEIBeY + TerAee / SiBCrA8M / n9bpLlRJkUb + URiGLoaj + XHym // fmCclAcveKlba6vKrcbqhEjsnY2F522yaTHcc1 + wXUWqif7rSIPhc0 + MT1hB1SZjd8dmPgtZUyzcL51DoChy + hZ4vLzE = <configuration> <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider"> <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <KeyName>RSA Key</KeyName> </KeyInfo> <CipherData> <CipherValue>RXO/zmmy3sR0iOJoF4ooxkFxwelVYpT0riwP2mYpR3FU+r6BPfvsqb384pohivkyNY7Dm4lPgR2bE9F7k6TblLVJFvnQu7p7d/yjnhzgHwWKMqb0M0t0Y8DOwogkDDXFxs1UxIhtknc+2a7UGtGh6Di3N572qxdfmGfQc7ZbwNE= </CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>KMNKBuV9nOid8pUvdNLY5I8R7BaEGncjkwYgshW8ClKjrXSM7zeIRmAy/cTaniu8Rfk92KVkEK83+UlQd+GQ6pycO3eM8DTM5kCyLcEiJa5XUAQv4KITBNBN6fBXsWrGuEyUDWZYm6Eijl8DqRDb11i+StkBLlHPyyhbnCAsXdz5CaqVuG0obEy2xmnGQ6G3Mzr74j4ifxnyvRq7levA2sBR4lhE5M80Cd5yKEJktcPWZYM99TmyO3KYjtmRW/Ws/XO3z9z1b1KohE5Ok/YX1YV0+Uk4/yuZo0Bjk+rErG505YMfRVtxSJ4ee418ZMfp4vOaqzKrSkHPie3zIR7SuVUeYPFZbcV65BKCUlT4EtPLgi8CHu8bMBQkdWxOnQEIBeY+TerAee/SiBCrA8M/n9bpLlRJkUb+URiGLoaj+XHym//fmCclAcveKlba6vKrcbqhEjsnY2F522yaTHcc1+wXUWqif7rSIPhc0+MT1hB1SZjd8dmPgtZUyzcL51DoChy+hZ4vLzE= </CipherValue> </CipherData> </EncryptedData> </connectionStrings> </configuration> 

Option # 1a Instead of encrypting with aspnet_regiis , you can move this encryption to your application. It simply discovers that the partitions to be protected are encrypted, and if not, they encrypt them. During development, you will need an option to avoid running this code before production.

Option number 2 . Encrypt the strings in the configuration file and use SecureString () to temporarily store the decrypted strings. This may or may not greatly increase the level of attack passed, depending on whether you use the APIs to support SecureString .

0
source

Source: https://habr.com/ru/post/1204347/


All Articles