Read Encrypted password from ConnectionString

Topics: Building and extending application blocks, Cryptography Application Block, Data Access Application Block
Mar 31, 2008 at 7:45 PM
I am using l logger.write (from logging app block) to log the data to database, there is no code involved, all the calls from logging app block to data access block is done by ent. lib configuration and code which is fine but there is a problem. my connectionstring password is encrypted and I want to find a (simple) way (preferably without changing ent. lib dlls), to be able to ask ent. lib data access app. block to use our password decryption code to read an already encrypted connection string password (done by our tool) and pass the decrypted password to logging application block.

I do not want to use ent. lib encryption method cause using the ent. lib config tool, everybody can see the password! the tool decrypt the connection string even if we encrypt connection string by changing the protectionprovided method of data access app block.

I tried one this solution: reading the config and dynamically update the password in the physical config file, but has two other problems first is I am not sure the timing for updating the con. str in app.config is before the time my app read the config and the 2nd is, as I am using enterpriseLibrary.ConfigurationSource selectedSource="File Configuration Source"> point our app..config to my wrapper config file (which is a app around ent. lib), the ConfigurationManager.ConnectionStrings0; is not able to understand to read the config from the path that ConfigurationSource is pointing to.
Apr 2, 2008 at 6:53 PM
Hi Andy,

I think the easiest way to deal with this is to have your own database class extending the "real" database class (let's say SqlDatabase) and add an explicit DbProviderMapping to override the database class to use for SQL Server connection strings. This new class' constructor will take the connection string with the encrypted password, decrypt it and pass it along to the parent class' constructor.

You'd need to:
  • Create your new database class inheriting from SqlDatabase.
  • Add a ctor to your new class that invokes the base class' ctor with the result of passing the connectionString through a static method that decrypts the pwd
  • Add a DatabaseAssembler attribute to your new class
  • Create the new class implementing the IDatabaseAssembler interface. Look at the SqlDatabaseAssembler for an example, it's very simple.
  • Add a db provider mapping entry in your configuration file from "System.Data.SqlClient" to your new database type.

Hope this helps,
Fernando

Apr 8, 2008 at 9:52 PM
Edited Apr 8, 2008 at 9:55 PM
I don't know if it helped Andy but it helped me. I do have to spend 4 hrs translating the steps to code (no really good documentation for Ent Lib). I wanted to share my implementation in case someone else gets to this page. I hope I can save you at least 10 seconds =D

I created this class to encrypt user, password and database name. I use a custom encryption method (removed from this example). I know about aspnet_regiis but my customer didn’t want to use that

******
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using Microsoft.Practices.EnterpriseLibrary.Data.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace Data
{
[DatabaseAssembler(typeof(EcryptedSqlDatabaseAssembler))]
public class EcryptedSqlDatabase : SqlDatabase
{
public EcryptedSqlDatabase(string connectionString) : base(DecryptConnectionString(connectionString)) { }
private static string DecryptConnectionString(string connectionString)
{
//replace next line with a nice/good decription method
string revVal = connectionString.Replace("Database=DatabaseName", "Database=RealName");
//return decripted connection string
return revVal;
}
}
public class EcryptedSqlDatabaseAssembler : IDatabaseAssembler
{
public Database Assemble(string name, ConnectionStringSettings connectionStringSettings, IConfigurationSource configurationSource)
{
return new EcryptedSqlDatabase(connectionStringSettings.ConnectionString);
}
}
}
*****

Note: use "Enterprise Library Configuration" tool to add this as "Custom Provider Mapping". It will eliminate the guess work.
“MY” configuration section follows. It is just for reference.. Don’t use it, I bet yours will be different:

<providerMappings><add databaseType="Data.EcryptedSqlDatabase, Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="System.Data.SqlClient" /></providerMappings>

If you want to build it by hand:

Class name including namespace => Data.EcryptedSqlDatabase,
Assembly name and version => Data,Version=1.0.0.0, (you can find those in your AssemblyInfo.cs file)

Hope this helps, =D
RIP
Apr 9, 2008 at 9:49 PM
Edited Apr 10, 2008 at 8:50 PM
Got it.