We have website that uses "NT Authority\Network Service".
Response.Write(WindowsIdentity.GetCurrent().Name);
We are currently using the following command to encrypt the config files.
aspnet_regiis -pc "NetFrameworkConfigurationKey"
aspnet_regiis -pa "NetFrameworkConfigurationKey" "NT Authority\Network Service"
aspnet_regiis.exe -pef "connectionStrings" "C:\WebAppLocation\Folder"
Note: We are not using "-exp". When we use "-exp" it is not creating RSA Key Container.
AS you can see, we are using the default key- NetFrameworkConfigurationKey. Our website has a load balancer. Webserver1(W1) and WebServer2 (W2) are available.
If I follow the above mentioned commands, we will be using separate keys on W1 and W2. However the website works with this approach.
Is this approach sufficient?
Does it got any shortcomings or secuirty holes?
Will it fail in any scenario?
Note: Machine key is added in our web.config. It is same in both config. However, our configProtectedData is not in the Web.Config. Also,I think, NetFrameworkConfigurationKey will be different in both the servers.
I have read the following msdn aricle for Encryption in Web Farm Scenarios.
http://msdn.microsoft.com/en-us/library/ff650304.aspx
I doesn't sound to me like you've done everything correctly. First of all, there's two issues here:
- Ensuring the
machineKey
is the same on both web servers.
- Ensuring the same RSA private key is installed in a key container on both servers so that the encrypted configuration can be decrypted by each server.
These are separate concerns: the machineKey isn't relevant for encrypting/decrypting the config section you want to protect.
So first of all the aspnet_regiis -pc
command is used to create a new RSA key container and the reason it's failing is that the container name you've specified already exists because it's the default. The keypair in this container is not exportable so you need to create a new key container and specify the -exp
switch to denote that the keypair is exportable.
aspnet_regiis -pc "MyDeploymentKeyContainer" -exp
Then export the key to a file, including the private key: the private key is used to decrypt the config section so the web server will need it.
aspnet_regiis -px "MyDeploymentKeyContainer" deploykey.xml -pri
Now add the config section to your web.config and save it.
<configProtectedData>
<providers>
<add keyContainerName="MyDeploymentKeyContainer"
useMachineContainer="true"
description="Uses RsaCryptoServiceProvider to encrypt and decrypt"
name="DeploymentProvider"
type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</configProtectedData>
Then encrypt the web.config section specifying the provider name as shown above (here it is "DeploymentProvider")
aspnet_regiis -pef "connectionStrings" "C:\WebAppLocation\Folder" -prov "DeploymentProvider"
Now you need to deploy the app to both servers and import the RSA key container you exported to the file earlier. Copy the file up and on each server run:
aspnet_regiis -pi deploykey.xml
Once that's done delete the file from the server - you don't want it hanging about. Finally grant the user account for the app pool running your web app access to the key container on both web servers.
aspnet_regiis -pa "MyDeploymentKeyContainer" SomeDomain\SomeAccount
Everything you are doing is fine, but also I recommend you putting the machinekey
in the machine.config
instead of the web.config
. This value normally does not change often and mitigates the chances of an accidental change when web.configs are altered.
This will also allow you to scale out future applications without mucking up more and more web.configs.
I have solved that in this way:
aspnet_regiis -pi "MyDeploymentKeyContainer" "c:\keys.xml"