System.Configuration.ConfigurationErrorsException saving config file after encrypting with RsaProtectedConfigurationProvider



Hi,

One of my users is getting a
System.Configuration.ConfigurationErrorsException when my Windows
Forms application tries to encrypt and save the application config
file, but it only happens for him and no other users!? I don't really
know anything about the security classes so don't have any idea where
to start looking.

He gets the exception when running the application on other users'
machines for whom it works fine, and other users are able to log in on
his machine and use the application. So I'm guessing it's something
to do with his profile but I have no idea where to look. He and all
other users have the same .NET version; I installed it as part of the
application install and noone had previous .NET runtimes on their
machine.

In my live application I get a standard windows box saying the program
had a problem and had to be closed, do I want to send info to MS.
(That's despite having set a ThreadException handler which normally
logs and shows a message for all unhandled exceptions, which is
slightly odd in itself.)

I created a test app to determine where it's failing, and it crashes
in this method:

private void btnProtectConfiguration_Click(object sender,
EventArgs e)
{
string provider = "RsaProtectedConfigurationProvider";

Configuration config = null;
config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

ConfigurationSection section = config.ConnectionStrings;

if ((section.SectionInformation.IsProtected == false) &&
(section.ElementInformation.IsLocked == false))
{
// Protect (encrypt) the "connectionStrings" section.
section.SectionInformation.ProtectSection(provider);

// Save the encrypted section.
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
}
MessageBox.Show("ok");
}


The info in the standard .NET exception handler is at the bottom of
this post.

In my test app he is able to save the config file fine without
encryption, using this code:
private void btnSaveConfig_Click(object sender, EventArgs e)
{
// Same stuff as ProtectConfiguration, but without the
protection.
// Checks if we can open and save the config file.
Configuration config = null;
config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection section = config.ConnectionStrings;
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
MessageBox.Show("ok");
}

He's also able to do RSA encryption and decryption using the
RSACryptoServiceProvider class; I included in my test app the sample
code here:
http://msdn2.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider(VS.80).aspx

If anyone can suggest why this exception could be occurring and why
it's attached to just this user I'd greatly appreciate it!

fyi the reason I'm doing this is that during application install my
application opens and encrypts the config file so connection details
can't be read by the casual observer. Not perfect security but good
enough, providing it runs!

many thanks,

- Rory


************** Exception Text **************
System.Configuration.ConfigurationErrorsException: An error occurred
executing the configuration section handler for connectionStrings. ---
System.Configuration.ConfigurationErrorsException: Failed to encrypt
the section 'connectionStrings' using provider
'RsaProtectedConfigurationProvider'. Error message from the provider:
Object already exists.
---> System.Security.Cryptography.CryptographicException: Object
already exists.

at
System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32
hr)
at System.Security.Cryptography.Utils._CreateCSP(CspParameters
param, Boolean randomKeyContainer, SafeProvHandle& hProv)
at
System.Security.Cryptography.Utils.CreateProvHandle(CspParameters
parameters, Boolean randomKeyContainer)
at
System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType
keyType, CspParameters parameters, Boolean randomKeyContainer, Int32
dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle&
safeKeyHandle)
at
System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
at
System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32
dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
at
System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters
parameters)
at
System.Configuration.RsaProtectedConfigurationProvider.GetCryptoServiceProvider(Boolean
exportable, Boolean keyMustExist)
at
System.Configuration.RsaProtectedConfigurationProvider.Encrypt(XmlNode
node)
at
System.Configuration.ProtectedConfigurationSection.EncryptSection(String
clearXml, ProtectedConfigurationProvider provider)
at
System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.EncryptSection(String
clearTextXml, ProtectedConfigurationProvider protectionProvider,
ProtectedConfigurationSection protectedConfigSection)
at
System.Configuration.Internal.DelegatingConfigHost.EncryptSection(String
clearTextXml, ProtectedConfigurationProvider protectionProvider,
ProtectedConfigurationSection protectedConfigSection)
at
System.Configuration.Internal.DelegatingConfigHost.EncryptSection(String
clearTextXml, ProtectedConfigurationProvider protectionProvider,
ProtectedConfigurationSection protectedConfigSection)
at
System.Configuration.MgmtConfigurationRecord.GetConfigDefinitionUpdates(Boolean
requireUpdates, ConfigurationSaveMode saveMode, Boolean forceSaveAll,
ConfigDefinitionUpdates& definitionUpdates, ArrayList&
configSourceUpdates)
--- End of inner exception stack trace ---
at
System.Configuration.MgmtConfigurationRecord.GetConfigDefinitionUpdates(Boolean
requireUpdates, ConfigurationSaveMode saveMode, Boolean forceSaveAll,
ConfigDefinitionUpdates& definitionUpdates, ArrayList&
configSourceUpdates)
--- End of inner exception stack trace ---
at
System.Configuration.MgmtConfigurationRecord.GetConfigDefinitionUpdates(Boolean
requireUpdates, ConfigurationSaveMode saveMode, Boolean forceSaveAll,
ConfigDefinitionUpdates& definitionUpdates, ArrayList&
configSourceUpdates)
at System.Configuration.MgmtConfigurationRecord.SaveAs(String
filename, ConfigurationSaveMode saveMode, Boolean forceUpdateAll)
at System.Configuration.Configuration.SaveAsImpl(String filename,
ConfigurationSaveMode saveMode, Boolean forceSaveAll)
at System.Configuration.Configuration.Save(ConfigurationSaveMode
saveMode)
at
DotNetTester.frmDotNetTester.btnProtectConfiguration_Click(Object
sender, EventArgs e) in C:\code\CAP\DotNetTester\DotNetTester
\Form1.cs:line 39
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at
System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at
System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32
msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)
CodeBase: file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
----------------------------------------
DotNetTester
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///C:/Documents%20and%20Settings/Ravi%20Tharmalingam/Desktop/DotNetTester%20v1.0/DotNetTester.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Drawing
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Security
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Security/2.0.0.0__b03f5f7f11d50a3a/System.Security.dll
----------------------------------------

.



Relevant Pages

  • System.Configuration.ConfigurationErrorsException saving config file after encrypting with RsaProtec
    ... Forms application tries to encrypt and save the application config ... He's also able to do RSA encryption and decryption using the ... param, Boolean randomKeyContainer, SafeProvHandle& hProv) ... clearTextXml, ProtectedConfigurationProvider protectionProvider, ...
    (microsoft.public.dotnet.framework.windowsforms)
  • Re: Help Encrypting Connection String
    ... I have simply 'overridden' the LocalSqlServer connection string to point to my SQL Server DB. ... to encrypt the section and places it into web.config - the config file then refers to the reg key. ... I don't like to hardcode anything, in general, but I'd rather do that with an encryption key than the underlying data itself. ...
    (microsoft.public.dotnet.framework.aspnet.security)
  • RE: Secure Remoting Across Domains/Workgroups
    ... I stored the username and password of my application ... onrecoverable because the encryption keys were machine-level. ... So what I ended up doing is creating a whole new section in the config file ... // Handle Exception ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Config files with different types
    ... So this works great for simple text config files. ... I'd also like to able to read '1' as an in, '1.0' as a float, ... I remember once I saw a script that took a string and tried int, ... When checking for Boolean you might want to ignore the case; ...
    (comp.lang.python)
  • Re: Help Encrypting Connection String
    ... there is a command line tool called aspnet_regiis that can do the encryption. ... It also looks like DPAPI uses a machine specific key, ... I have simply 'overridden' the LocalSqlServer connection string to point to my SQL Server DB. ... There are a lot of wrappers out there, e.g. http://www.leastprivilege.com/DPAPITools.aspx the tool you are referring to is called aspnet_setreg - it uses DPAPI to encrypt the section and places it into web.config - the config file then refers to the reg key. ...
    (microsoft.public.dotnet.framework.aspnet.security)