Decrypt Errors on app.config

Topics: Cryptography Application Block, Data Access Application Block
May 15, 2007 at 3:28 PM
I used the new Enterprise Library 3.0 to encrypt the connection string in my app.config file. I choose DataProtectionConfigurationBlock as the Protection Provider.

When I run the app on my development computer it works great. But when I copy the app on another workstation and try to run it I get the following error:

Failed to decrypt using provider 'DataProtectionConfigurationProvider'. Error message from the provider: Key not valid for use in specified state.
May 15, 2007 at 4:57 PM
If you protect your data using DPAPI the encrypted data can only be read from that particular machine. Here is more information on how DPAPI works:

Windows Data Protection

For DPAPI, you will need to run the config tool and encrypt on each machine.

If you want the freedom of moving a single encrypted config file you would need to use the RSA Encryption Method and manage the keys. Here is more on that:

Walkthrough: Encrypting Configuration Information Using Protected Configuration

Walkthrough: Creating and Exporting an RSA Key Container

If you don't have the luxury of that, you can use the protection routines directly that I talk about in this tutorial:

Encrypt Connection Strings AppSettings and Web.Config in ASP.NET 2.0 - Security Best Practices

I typically do that when using a shared host since I don't have physical access to the server and some hosts won't help you with this stuff.

Regards,

Dave

___________________________________

David Hayden
Microsoft MVP C#
Jun 7, 2007 at 12:43 PM
Interesting. But I have a problem to manage the keys. Ok, i can create new keys, export them, import them. But if I set RsaProtectedConfigurationProvider for the DAAB the called keyname is a simple 'Rsa Key'.

1st issue: i cannot export this key:
aspnet_regiis -px "Rsa Key" "c:\rsakey.xml" -pri results in ...The RSA key container was not found...

2nd issue:
I dont know how to use a self created key container within the app.config - what i would prefer.. Simply change the container name in app.config produces an error while the application tries to read the config-file.

Any ideas or hints?

Axel.
Jun 9, 2007 at 6:07 PM
I am having the exact same problem exporting the key to use on another server. I have tried creating a key container named "Rsa Key", export it and then import on a another server. This does not work.
Using filemon I see that when I select RsaProtectedConfigurationProvider a file is created in "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys" named d6d986f09a1ee04e24c949879fdb506c_104b9789-37fe-4a23-b07e-4b3b19babf65
When I try to export the key "Rsa Key" I get error "The RSA key container was not found". I created the key using "aspnetregiis -pc "Rsa Key"–exp". This created a file of a different name. I then try to export that key and get error "The RSA key container was not found". In filemon it shows that aspnetregiis is looking for a file of a totally different name than what was originally created by aspnet_regiis.
I am at a lost on how to export the key that the Enterprise Library Configuration tool creates.

Any help would be much appreciated.

Thanks, Brad
Jun 15, 2007 at 10:43 AM
any hint?
Jul 9, 2007 at 6:15 PM
This seems to work for using custom keys.

add the following lines to the config file in the providers section
<remove name="RsaProtectedConfigurationProvider" />
<add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="mykey" cspProviderName="" useMachineContainer="true" useOAEP="false" />

use this command to create the key
Aspnet_regiis -pc "mykey" -exp

use Aspnet_regiis to export the key on your primary machine
Aspnet_regiis -px "mykey" "c:\mykey.xml" -pri

Copy the mykey.xml file to the other computers hard drive
then just register the new keys on the other machines
Aspnet_regiis -pi "mykey" "c:\mykey.xml"

I used Enterprise library 3.0 GUI to encrypt the file.

Hope this helps
Jul 10, 2007 at 10:51 AM
Fine, I will try this. Thank you :)
Jul 11, 2007 at 9:45 PM
Thanks for your help. This worked for me. I added this to my app.config:

<configProtectedData>
<providers>
<remove name="RsaProtectedConfigurationProvider" />
<add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="mykey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
</providers>
</configProtectedData>

Does this solution indicate a bug or is this something that maybe the Enterprise library GUI should provide for? Or just one extra step in order to use the RSA provider?


shane2007 wrote:
This seems to work for using custom keys.

add the following lines to the config file in the providers section
<remove name="RsaProtectedConfigurationProvider" />
<add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="mykey" cspProviderName="" useMachineContainer="true" useOAEP="false" />

use this command to create the key
Aspnet_regiis -pc "mykey" -exp

use Aspnet_regiis to export the key on your primary machine
Aspnet_regiis -px "mykey" "c:\mykey.xml" -pri

Copy the mykey.xml file to the other computers hard drive
then just register the new keys on the other machines
Aspnet_regiis -pi "mykey" "c:\mykey.xml"

I used Enterprise library 3.0 GUI to encrypt the file.

Hope this helps

Dec 10, 2007 at 6:19 AM
What if it's a SCSF application and the client machine isn't running iis?
Dec 10, 2007 at 6:49 PM
Hi,


jackw2 wrote:
What if it's a SCSF application and the client machine isn't running iis?


aspnet_regiis is part of the standard .NET bundle.

Fernando
Dec 26, 2007 at 9:29 PM
Hi, if you need to encrypt a connection string in a windows application and you import a symmetric key to the client wouldn't the user on that client machine be able to write an application that uses the cryptography api and get the plain text connection string for your app.config?

I don't know how to make sure only your app is able to decrypt the connection strings used by your app. After all, the user has access to the encrypted string and the machine has the symmetric key that was used to encrypt it... Is there any way to avoid this without sending all business logic and data access to an application server?

Thanks
Dec 27, 2007 at 11:03 AM
Hi,

Configuration protection is really managed by the .NET framework, so you'd have to play by its rules.

I haven't really tried this, and it would only work if you strong name your app (which is a sensible constraint for your requirement IMHO), but you could create your own protected configuration provider (extending the Rsa one) that demands a StrongNameIdentityPermission permission before decrypting an element. This permission should be the union of an identity permission for your public key and the .NET framework's public key (the one for which "b03f5f7f11d50a3a" is the token), to allow for the framework to be in the call chain, and this means you would need to create the permissions in code instead of relying on permission attributes.

Here are a few links that should help you:

If you give this a try, please post your experience back to this thread.

Regards,
Fernando



acs wrote:
Hi, if you need to encrypt a connection string in a windows application and you import a symmetric key to the client wouldn't the user on that client machine be able to write an application that uses the cryptography api and get the plain text connection string for your app.config?

I don't know how to make sure only your app is able to decrypt the connection strings used by your app. After all, the user has access to the encrypted string and the machine has the symmetric key that was used to encrypt it... Is there any way to avoid this without sending all business logic and data access to an application server?

Thanks

Dec 27, 2007 at 11:25 AM
Too bad, RsaProtectedConfigurationProvider is sealed, so extending it won't work. Wrapping an instance may work, though.


fsimonazzi wrote:
Hi,

Configuration protection is really managed by the .NET framework, so you'd have to play by its rules.

I haven't really tried this, and it would only work if you strong name your app (which is a sensible constraint for your requirement IMHO), but you could create your own protected configuration provider (extending the Rsa one) that demands a StrongNameIdentityPermission permission before decrypting an element. This permission should be the union of an identity permission for your public key and the .NET framework's public key (the one for which "b03f5f7f11d50a3a" is the token), to allow for the framework to be in the call chain, and this means you would need to create the permissions in code instead of relying on permission attributes.

Here are a few links that should help you:

If you give this a try, please post your experience back to this thread.

Regards,
Fernando



acs wrote:
Hi, if you need to encrypt a connection string in a windows application and you import a symmetric key to the client wouldn't the user on that client machine be able to write an application that uses the cryptography api and get the plain text connection string for your app.config?

I don't know how to make sure only your app is able to decrypt the connection strings used by your app. After all, the user has access to the encrypted string and the machine has the symmetric key that was used to encrypt it... Is there any way to avoid this without sending all business logic and data access to an application server?

Thanks


Dec 27, 2007 at 12:47 PM
And it will only "protect" in partial trust http://blogs.msdn.com/eugene_bobukh/archive/2005/05/06/415217.aspx.
You may want to perform a stack walk of your own, but it will kill your performance (see http://msdn2.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx).

Fernando


fsimonazzi wrote:
Too bad, RsaProtectedConfigurationProvider is sealed, so extending it won't work. Wrapping an instance may work, though.

Dec 27, 2007 at 12:51 PM
Edited Dec 27, 2007 at 12:54 PM
[erased duplicate]
Aug 8, 2008 at 5:04 PM
The RSA key that is used by enterprise library is NetFrameworkConfigurationKey.

To give permissions to aspnet user, you only have to do aspnet_regiis -pa "NetFrameworkConfigurationKey" "aspnet"

Tiago