Credential storage best practices

雨燕双飞 提交于 2019-12-21 05:17:10

问题


I'm writing a Windows service and need to make authenticated web requests. The service will not be running under the ownership of the credentials used to make the request; this implies that I need to store the credentials for the request in some way.

What are the best practices here? The credentials will need to be stored in App.config (or an analog); I'd rather not have the password hanging out in plain text. As passwords change frequently, building or otherwise baking in the password to the binary is not an option.

The same question applies for Powershell. I need to make authenticated requests, but I don't want the script to contain in a plain-text form the credentials used for the requests.


回答1:


Can't take the credit for the answer: But here's a blog post called "Encrypting Passwords in .NET App Config" With full code included.

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




回答2:


I always refer to Keith Brown's "The .NET Developer's Guide to Windows Security" book for stuff like this.

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

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




回答3:


Option #1: Encrypt sections in your App.config for Web.config file using the ProtectSection() method. This is designed to work for Web and Desktop apps and also web farms that rely on replicating Web.config files with encrypted sections.

In depth MSDN tutorials covering use of RSA provider:

  • Encrypting Configuration Information Using Protected Configuration:

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);

}

Older approach using DPAPI provider:

  • How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI

To encrypt:

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

To decrypt :

aspnet_regiis -pd "connectionStrings" -app "/SampleApplication"
  • Encrypt/Decrypt command reference

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>

Option #1a Instead of performing the encryption using aspnet_regiis, you can move this encryption into your app. It just detects if the sections you need to secure are encrypted and if not, it encrypts them. You'll need an option during development to avoid running this code until production.

  • Examples

Option #2 Encrypt strings in your config file and use SecureString() to temporarily store the decrypted strings. This may or may not get you much attack surface mileage depending on whether the APIs you're using the strings for support SecureString.

  • Examples


来源:https://stackoverflow.com/questions/508608/credential-storage-best-practices

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!