Friday, May 24, 2013

Publishing encrypted connection strings in web.config


PROBLEM: You publish your website to a server (e.g. Stage or Production) and then have to manually run a command to encrypt the connectionStrings within the web.config (would be nice for the publish process to just take care of everything) - this guy on stackoverflow had the same issue: http://stackoverflow.com/questions/14838156/encrypting-webconfig/16728000

SOLUTION: Take the encrypted portion of the web.config (remember you'll need to be remoted on to your server to do the encryption) and add to your Web.[CONFIGURATION].config transformation file e.g. Web.Stage.config or Web.Release.config... since the encryption is based on machine keys you'll need to have a different transformation file for each server that you are deploying to.  This is all quite simple, I just never thought of doing it before - the hardest bit was finding the syntax for the web.config transformation file - the syntax I've got below works but the compiler will flag a warning about invalid syntax i.e.


Warning 15 The element 'connectionStrings' has invalid child element 'EncryptedData' in namespace 'http://www.w3.org/2001/04/xmlenc#'. List of possible elements expected: 'add, remove, clear'. C:\DevTFS\YourProject\Web.Stage.config 14 6 YourProject

 (I'm open to suggestions on how to make it compliant and still work).


Step 1.
Encrypt connectionStrings in the web.config as per: http://msdn.microsoft.com/library/dtkwfdky.aspx or http://stackoverflow.com/questions/8230864/how-can-i-safely-store-and-access-connection-string-details

I keep a batch file in the root of my website for this:


@ECHO OFF
echo "This will Encrypt or Decrypt the Connections section of web.config - it should be run after deploying to any publicly accessible version of the site e.g. production."

CHOICE /C:ed /M "Encrypt or Decrypt"

IF %errorlevel%==1 goto enc
IF %errorlevel%==2 goto dec

:enc
echo "Encrypting section connectionStrings"
c:\WINDOWS\Microsoft.net\Framework\v4.0.30319\aspnet_regiis -pef "connectionStrings" %CD%
goto EOF

:dec
echo "Decrypting section connectionStrings"
c:\WINDOWS\Microsoft.net\Framework\v4.0.30319\aspnet_regiis -pdf "connectionStrings" %CD%
GOTO EOF

:EOF
EXIT



Step 2.

Add the following to your Web.[Config].config file...


  <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider"
  </connectionStrings>

And then copy and paste the <EncryptedData> elements from your encrypted web.config file on your server between these tags e.g.


  <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider" xdt:Transform="Replace">
    <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>t8p7aOZTjMon8B1qC4L4gmKasdfsdafasdfJHckY0fl9hfaasdffQWrpdX1jqF6vD3/X4Ejg+UeiCWujkx+dfvDOif3sodfsdfsd6kHAtah2o59UmzsfdasdfdfdKzUliSgMe01fRbjA/bxA6Bbq+sjzE6FAAI=</CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>Vy1TZWY8ojpf343XQCQwK/r4lmp+vbJPS5sdfdfbv0YMTGEdGuCwdLND5ezMe9iLkuI5/fmvU1TSDzPgvKcAwNc1rXU5jiU0234234JtviOMe6vjU8FSkHilwLITGS9/XUDiacqccfuXsBcdBtcwAfBxIAwwCQxOQIFi6hN/cG2emFj1oSIU468O8ezOG+UMSd4HzaDS2jzZyrfsdfsdfyi0bg8OV5QVOlSUjjuh54Bt4t2pd0O2vsUbwsdfsdfVxB0KgIlL6Kqe53z2Ns6GHlRwJuMFRHQnQT234234SSVLLGkWdI1IGyl12JdlTrd5JItDHGgPNat+fe5FR5GNasdfsdfivft4YZV3iXgbPtZyiHm6aI7ccDuCTHJ+V78AwZAVlIGRKzVbqsic+Qg6T7U</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>


Credit goes to this guy for actually adding a useful comment to forums.asp.net (unfortunately they are few and far between) - http://forums.asp.net/post/5390287.aspx

7 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Hi,

    This is what I am looking for but I am a little confused with the implementation.

    My requirements are

    Web.Debug.Config- Pointing to db1
    Web.Production.config- Pointing to db2
    Web.config- Encrypted with RSA key.

    When I replace the encrypted key in debug and production config files, how do I make sure it is pointing to the right db for each environment?

    ReplyDelete
  3. Hi Mihir-d, I need a bit more info about your environments... do you just have two environments - local (debug) and production (on a separate server)?

    If that's the case you would typically have the local/debug connection string in just the web.config file, and then in the web.config.Production file you'd have the transformation from the blog post that replaces the value as per web.config with the encrypted value from the production server.

    When publishing to production simply ensure you're using the Production build configuration, which will cause the web.config to be transformed using the web.config.production transformation file.

    Let me know if you have any further questions.

    ReplyDelete
    Replies
    1. Currently, I have 8-10 environments (test, multiple production, QA and staging) with different connection strings.

      As you mentioned, in my main web.config I have my main connection strings which is encrypted (not sure if this should be encrypted or not. Currently, I have encrypted it using asp net regiis). I have the following queries

      • Should my web.production.config be encrypted? If yes, how do we apply transforms to encrypted connection strings?
      • If I want to change my connection string, how do I decrypt it
      • Is it a good practice to encrypt each environments (production, QA, staging etc..) connection string?

      Any examples for encryption for different connection strings are highly appreciated

      Delete
    2. Hi Mr R,

      Did you get a chance to read my queries above?

      Delete
  4. Have a read of these if the concept of web.config transformations isn't yet clear to you: https://msdn.microsoft.com/en-us/library/dd465318(v=vs.100).aspx OR https://docs.microsoft.com/en-us/aspnet/web-forms/overview/deployment/visual-studio-web-deployment/web-config-transformations

    ReplyDelete
    Replies
    1. Hi,

      Thank you for the links. I have completed web config transforms.

      Delete