Encrypting externally stored App blocks with exportable Key Provider - encryption

I have been trying for quite a while to figure out how to encrypt Application blocks that are stored in an external file called dev_entlib.config
I can see in entlib (4.1) that it's possible to use the default protection providers to encrypt the blocks but, I really need to deploy this Application on different servers and thus I would need to export the keyProvider used to encrypt the application blocks to those servers.
What I've done so far is to add a custom Protected Configuration Provider to the machine.config file in the .net v2.0* whatever folder (and all the target servers)
the custom provider is like this
<add name="MyCompanyProvider"
type="System.Configuration.RsaProtectedConfigurationProvider,
System.Configuration, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a,
processorArchitecture=MSIL"
keyContainerName="MyKey"
useMachineContainer="true" />
that sits nicely beside the other default providers and even has design time support in the Entlib config tool. I then choose the protection provider for each block I want to encrypt.
Looking at the dev_entlib.config, shows that indeed the block was encrypted with my provider. My provider uses my key container. Therefore the block should be encrypted using my key container. I then Export "MyKey" to an xml file using:
c:\Windows\Microsoft.NET\Framework\v2.0.50727>aspnet_regiis.exe -px "MyKey" "C:\keys.xml" -pri
Exporting RSA Keys to file...
Succeeded!
This key file is then copied to my sysTest server where it is imported and has access rights granted to "NT Authority\Network Services" and "ASPNET"
I then copy over my encrypted web.config and dev_entlib.config and try to display the connection strings in a small page which uses .net ConfigurationManager to get the ConnectionStrings collection and display them on the page. This page is running under IIS and the identity of the process is "NT Authority\Network Services".
The problem is, that it doesn't work! There are bad data errors or "failed to decrypt using provider MyCompanyProvider".
This approach seems to make logical sense to me but it still fails.
Does anyone have another suggestions?

Encrypt external Enterprise Library configuration files with your custom RSA key container using the Enterprise Library Configuration tool.
EntLib (4.1) uses the default protection provider RsaProtectedConfigurationProvider. But it is possible to remove this provider within your configuration file and replace it with your own with the same name which can then point to your custom key provider: "MyKey".
You should add this configProtectedData section in the configuration file that has the region that you want to encrypt (e.g. your external file: *dev_entlib.config*). You do not need to modify the machine.config file at all.
You can then choose the RsaProtectedConfigurationProvider from the Enterprise Library Configuration application for the Data Access Application Block ProtectionProvider.
You have to open this EntLibConfig.exe with Run as administrator if you are on Vista, Windows 7, Windows 2008.
Otherwise you will get an error:
Failed to encrypt the section 'connectionStrings' using provider 'RsaProtectedConfigurationProvider'. Error message from the provider: Object already exists.
You can then copy this encrypted *dev_entlib.config* along with the web.config configuration file to your sysTest server. Open up the web.config file with Enterprise Library Configuration tool on that sysTest server should not get the error:
Failed to decrypt using provider 'RsaProtectedConfigurationProvider'. Error message from the provider: Bad Data.
web.config
This file is pretty much empty and just points to the external Data Configuration file:
<!-- web.config -->
<configuration>
<configSections>
<section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<enterpriseLibrary.ConfigurationSource selectedSource="External Data Configuration File Source">
<sources>
<add name="External Data Configuration File Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
filePath="dev_entlib.config" />
</sources>
</enterpriseLibrary.ConfigurationSource>
</configuration>
dev_entlib.config
This file has the connection strings and the protection provider with which it should be encrypted with:
<!-- dev_entlib.config -->
<configuration>
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<dataConfiguration defaultDatabase="MyConnectionStringName" />
<connectionStrings>
<add name="cnHnicMediaLibrary" connectionString="Server=MyDbServer; Database=MyDbName; Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
</connectionStrings>
<configProtectedData>
<providers>
<remove name="RsaProtectedConfigurationProvider" />
<add name="RsaProtectedConfigurationProvider"
keyContainerName="MyKey"
useMachineContainer="true"
description="Uses our own encryption key container so that it will work in a Web Farm setting. We need to trick Enterprise Library, which wants to use the default RsaCryptoServiceProvider to encrypt and decrypt, by replacing this default provider with our own while this configuration is processed!"
type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</configProtectedData>
</configuration>
Based on:
http://entlib.codeplex.com/discussions/237555 (AvanadeSupport, Dec 8 2010 at 11:37 PM)
http://entlib.codeplex.com/discussions/10300 (shane2007, Jul 9 2007 at 1:15 PM)
http://entlib.codeplex.com/discussions/213998 (need to change the version back to 2.0.0.0)
I hope that this described the error message that you had and how to fix it.

It doesn't seem to be possible yet. My solution is to just encrypt the blocks as part of the web.config and then copy and paste those blocks into an external entLib.config file. These block should then be able to be decrypted on the target servers with the exported key.

Related

From where i can find the PublicKeyToken & Version for my <membership> <providers>

I am working with an asp.net mvc web application, and i need to connect to remote domain, so i added the following to my web.config:-
<membership>
<providers>
<add name="TestDomain1ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="TestDomain1ConnectionString" connectionUsername="....." connectionPassword="....." />
but i am not sure what does Version and PublicKeyToken represetns and from where i can find them ? and if i do not specify these values will my provider be valid ?
Thanks
As that's a regular framework assembly, it will be deployed on GAC; to discover full assembly name you can access that class documentation on MSDN.
There you'll find that class resides on System.Web assembly. Now you can navigate to c:\windows\assembly folder and locate the assembly which matches desired version, right click it and copy the public key token.
Is that information doesn't match the version and public key token on your web.config file, .NET framework can't locate it and, you'll get a missing assembly exception.

Unobtrusive Oracle Deployment on Windows Server 2008

I have a .NET 4.0 Web Forms app that I am running with the beta Oracle EF-aware data provider, and I want to perform "unobtrusive" Oracle deployment to a Win2K8 box, as shown in many SO solutions.
There is an existing Oracle Instant Client installation on the Win2K8 box, which I can neither work with nor remove, and it has an entry in the PATH environment variable on the Win2K8 box. According to this SO answer, I do not need to set PATH for my Oracle DLLs, since I have DllPath set in the web.config.
I am following the procedure from here, yet I still get the provider is not compatible with the version of Oracle client error.
Here's my (unsuccessful) setup, as of now:
Oracle DLLs are in my web app's bin directory, and set to Copy Always Do Not Copy.
Platform and Platform Target settings are set to x86 in my local Build Configuration.
32-bit applications are enabled in the app pool (.NET 4.0) on the Win2K8 box.
Oracle DLLs are not present in the GAC, not are they present in the GAC_32 and GAC_64 directories on the Win2K8 box.
My web.config (but not my Win2K8 machine.config) contains this:
<configuration>
<configSections>
<section name="oracle.dataaccess.client" type="System.Data.Common.DbProviderConfigurationHandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<oracle.dataaccess.client>
<settings>
<add name="DllPath" value="C:\inetpub\wwwroot\myapp\bin"></add>
<add name="FetchSize" value="65536"></add>
<add name="StatementCacheSize" value="10"></add>
<add name="TraceFileName" value="c:\temp\odpnet2.log"></add>
<add name="TraceLevel" value="0"></add>
<add name="TraceOption" value="0"></add>
</settings>
</oracle.dataaccess.client>
<system.data>
<!-- Version=4.112.2.50 -->
<DbProviderFactories>
<add name="Oracle Data Provider for .NET" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess, Version=4.112.2.50, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="MyEntities" connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=Oracle.DataAccess.Client;provider connection string="DATA SOURCE=**<using EZCONNECT format here>**" providerName="System.Data.EntityClient" />
</connectionStrings>
<configuration>
The app itself deploys successfully, and I can run pages that do not reference my Oracle DLLs. But, for those that do reference Oracle, I still get the provider compatibility error.
What am I missing?
Thanks again for the help.
UPDATE: The web app runs on the Win2K8 target with .NET 4.0, EF4.1, and the Oracle EF Provider, completely separate from the other active ODAC install. No PATH variable, no installation from Universal Installer, no Oracle DLLs in GAC.
Case closed. I was missing an Oracle DLL.

Membership provider name and type for Microsoft WebMatrix's sample Template

What is the membership provider name and type is used in the Microsoft Webmatrix's template site? In the web.config it is not given. When I run it locally, the template works but when I publish, it gives the following error:
Parser Error Message: The connection name 'LocalSqlServer' was not found in the applications configuration or the connection string is empty.
Source Error:
Line 239: <providers>
Line 240: <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, ....
Source File: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config Line: 240
Any help will be appreciated.
The Database used in the application is SQLCE4.
Web Pages uses the SimpleMembershipProvider which is located in WebMatrix.WebData.
I don't believe there's a default Membership provider that supports SQL Server Compact Edition 4. There is a Membership provider implementation that does out on CodePlex: http://sqlcemembership.codeplex.com/
So, if you're using that already, then ensure that you have a connection string defined in your config file, like so:
<connectionStrings>
<add name="LocalSqlServer"
connectionString="data source=|DataDirectory|\YourDatabaseName.sdf"/>
</connectionStrings>
And your provider specified in your config should define the connectionStringName attribute and reference the connection string's name defined in the <connectionStrings> block, like this:
<providers>
<clear/>
<add name="SqlCeMembershipProvider"
type="ErikEJ.SqlCeMembershipProvider"
connectionStringName="LocalSqlServer"
.... />
</providers>
A config sample is provided with that SQL CE 4 Membership provider on the main project page.

Mono with SQL Server Membership Provider?

Apparently Mono replaces references to SQL Server membership provider with sqlite membership provider (see ASP.NET_Settings_Mapping). Is there any way to convince Mono to use SQL Server for the membership provider?
When I try to log in to my web app, I get the following:
System.Configuration.Provider.ProviderException: Operation aborted due to an exception (see Trace for details).
at System.Web.Security.SqliteMembershipProvider.ValidateUser (string,string) <0x003bb>
at DirectMail.Controllers.AccountMembershipService.ValidateUser (string,string) [0x00000] in [file].cs:404
at DirectMail.Controllers.AccountController.ValidateLogOn (string,string) [0x00040] in [file].cs:346
at DirectMail.Controllers.AccountController.LogOn (string,string,bool,string) [0x00000] in [file].cs:79
at (wrapper dynamic-method) System.Runtime.CompilerServices.ExecutionScope.lambda_method (System.Runtime.CompilerServices.ExecutionScope,System.Web.Mvc.ControllerBase,object[]) <0x001c1>
at System.Web.Mvc.ActionMethodDispatcher.Execute (System.Web.Mvc.ControllerBase,object[]) <0x00028>
at System.Web.Mvc.ReflectedActionDescriptor.Execute (System.Web.Mvc.ControllerContext,System.Collections.Generic.IDictionary`2<string, object>) <0x0015b>
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod (System.Web.Mvc.ControllerContext,System.Web.Mvc.ActionDescriptor,System.Collections.Generic.IDictionary`2<string, object>) <0x00036>
at System.Web.Mvc.ControllerActionInvoker/<InvokeActionMethodWithFilters>c__AnonStoreyB.<>m__E () <0x00092>
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (System.Web.Mvc.IActionFilter,System.Web.Mvc.ActionExecutingContext,System.Func`1<System.Web.Mvc.ActionExecutedContext>) <0x00125>
The top of the file /usr/local/etc/mono/4.0/settings.map on one Debian Linux machine is:
<?xml version="1.0" encoding="utf-8" ?>
<settingsMap>
<map sectionType="System.Web.Configuration.MembershipSection, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
mapperType="Mono.Web.Util.MembershipSectionMapper, Mono.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"
platform="Unix">
<!-- The 'what' tag specifies which region of the section to modify. The 'value' attribute value is mapper-specific and is not defined here. It can be
any expression understood by the mapper to designate the section region to modify.
-->
<what value="providers">
<!-- 'what' can contain any number of occurrences of any three elements:
replace - replace the designated region
add - add a new entry to the region
clear - clear the region
remove - remove the designatedregion
The attributes to any of the above are freeform and are not processed by the mapper manager. They are stored verbatim for the
mapper to peruse.
-->
<replace name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqliteMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqliteServer" />
</what>
</map>
<!-- ... -->
On the ASP.NET Settings Mapping page that you linked to, in the section titled "Inhibiting the settings mapping", it says that adding:
<appSettings>
<add key="MonoAspnetInhibitSettingsMap" value="anything"/>
</appSettings>
to your app's Web.config file will disable settings mapping. I found, however, that value "anything" does not work. If I use the value "true" instead, then it does:
<appSettings>
<add key="MonoAspnetInhibitSettingsMap" value="true"/>
</appSettings>
This must be a misconfiguration because an implemented sqlmembershipprovider exists for Mono 2.0. It is using a DBProviderFactory to obtain a connection. A SqlClient implementation is also there so that only leads to the conclusion that the web.config for the website is not correct, which is not unthinkable because sqlclient and sqlite almost looks the same in an overcrowded web.config.
If anyone can post that one, that might clarify the problem at hand.

Trying to use encrypted system.web/identity on web service errors with "Failed to decrypt using provider"

I'm receiving the following error when trying to access a web service that is using (for temporary reasons) an encrypted system.web/identity entry:
Failed to decrypt using provider 'DataProtectionConfigurationProvider'. Error message from the provider: The RSA key container could not be opened.
I've followed the steps found in comments at http://blogs.msdn.com/mosharaf/archive/2005/11/17/protectedConfiguration.aspx, and these are the steps I've done:
Added "xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"" to the configuration attribute in the web service's web.config
Create a container using aspnet_regiis -pc "DataProtectionConfigurationProviderKeys" -exp
Added the following to the web.config:
<configProtectedData>
<providers>
<clear />
<add name="DataProtectionConfigurationProvider"
type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL"
keyContainerName="DataProtectionConfigurationProviderKeys"
useMachineContainer="true" />
</providers>
</configProtectedData>
Granted access to the key container to the account IIS is running under: aspnet_regiis -pa "DataProtectionConfigurationProviderKeys" "eca\iusr_xxxxx". I also granted access to the impersonated account (e.g. the one in the identity attribute) using the same command.
I then encrypted the system.web/identity entry: aspnet_regiis -pef "system.web/identity" "C:\ddrive\EcaDevelopment\EcaApplicationsNet2\Projects\TASV2\Mainline\src\TASV2.WordToPdf.WebSvc" -prov "DataProtectionConfigurationProvider"
But, when I try to run my test harness against the web service, I get:
Failed to decrypt using provider 'DataProtectionConfigurationProvider'. Error message from the provider: The RSA key container could not be opened.
What have I missed out? Can I actually encrypt just the identity tag? I can encrypt and use the connectionStrings no problem...

Resources