views:

1023

answers:

2

When using ASP.NET protected configuration, how can I encrypt the config with just the public key?

I can export a public key file. I would like to then use this public key to encrypt the configuration files on another server for later deployment. However, I can't figure out how to get aspnet_regiis to use the exported public key.

Basically, I tried importing just the public key into a container, and then encrypt it. However, when I do that, instead of using the existing key to encrypt, it creates an entirely new key pair, overwriting the existing public key. In the script below, if you rename each of the copied files back to connections.config, and try to decrypt them, the first one (connectionstring_server.encrypted) will fail, while the second (connectionstring_build.encrypted) will succeed), proving that a new keypair was created.

Here is a batch file that demonstrates the approach I have tried (edit: this is just an example to test the aspnet_regiis capabilities. My actual usage of it would, obviously, be slightly different) :

REM delete container in case it already exists
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pz "MyKeys"

REM create container
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pc "MyKeys"

REM export key
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -px "MyKeys" "publicKey.xml"

REM encrypt file
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pef "connectionStrings" . -prov "MyProvider"

REM copy encrypted file for later comparison
copy connections.config connectionstring_server.encrypted
pause

REM decrypt file
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pdf "connectionStrings" .

REM delete continer
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pz "MyKeys"

REM import public key
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pi "MyKeys" publicKey.xml

REM encrypt file with just public key - THIS DOES NOT WORK CORRECTLY, it creates a new keypair
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pef "connectionStrings" . -prov "MyProvider"

REM copy back encrypted file
copy connections.config connectionstring_build.encrypted
pause

REM decrypt file
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pdf "connectionStrings" .

And here is a sample web.config

<?xml version="1.0"?>
<configuration>
    <configProtectedData>
     <providers>
      <add name="MyProvider" keyContainerName="MyKeys" type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" useMachineContainer="true" />
     </providers>
    </configProtectedData>
  <connectionStrings configSource="connections.config" />
</configuration>

And the corresponding connections.config:

<connectionStrings>
  <add name="SomConnectionName" connectionString="Data Source=somedatasource; Initial Catalog=somedatabase; Integrated Security=SSPI; Persist Security Info=False;" providerName="System.Data.SqlClient" />
</connectionStrings>

Edit: Answer suggested below that I could export the private key as well. That would indeed allow the encryption to work, but I shouldn't need the private key to encrypt. What I want to do is leave the private key just on the server that will use the config file, and store the public key in a more accessible place. Is the inability to do this simply a limitation of aspnet_regiis?

+1  A: 

I think your problem is in the export command, when you export you need to specify the -pri argument to tell aspnet_regiis that you want to export the private key as well as the public key.

REM export key
\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -px "MyKeys" "publicKey.xml" -pri

Without the private key your import is still creating its own keypair. This may be a Microsoft bug, aspnet_regiis should at least warn you that it was not able to import your incomplete key and that it made a new one instead...

Exporting just the public key could be useful, you could then give your operations or development group the xml file and they would be able to encrypt the config file before it is deployed to the server without having to divulge the private key. Also, this way you wouldn't need to run the encryption process on each server in your farm.

joshperry
A: 

I don't know if it's a bug or not, but I've definitely run into this problem as well. The public AND private keys need to imported into the Windows key store for any of the .net functions to work. However, the private key can be protected by not specifying the -exp switch when importing the key.

Robert C. Barth