Here is a modified ModuleConfig class which uses an encrypted
configuration file. The only change to the web.config file you need to
make is to add a "SiteID" key under AppSettings which should have your
key for encryption. You may want to use an alternative way of storing
your key, but you can't store it in the database because you need the
configuration file to get the connection string. This class will try to
find a .Encrypted.Config file. If none exists, it will open the
unencrypted .Config file and immediately save it as an encrypted
.Encrypted.Config file. You can then delete or move the original
.Config file. Here is the code:
using System.Security.Cryptography;
public class ModuleConfig
{
public static ModuleSettings GetSettings()
{
string secretPhrase
ConfigurationSettings.AppSettings["SiteID"];
CryptoStream decryptStream = null; //
Stream used to encrypt
RijndaelManaged rijndael = null; //
Rijndael provider
ICryptoTransform rijndaelDecrypt = null; //
Encrypting object
FileStream fs = null; //
// Initialize internal values
byte[] _Key = new byte[24];
byte[] _IV = new byte[16];
// Perform a hash operation using the phrase.
This will
// generate a unique 32 character value to be
used as the key.
byte[] bytePhrase
Encoding.ASCII.GetBytes(secretPhrase);
SHA384Managed sha384 = new SHA384Managed();
sha384.ComputeHash(bytePhrase);
byte[] result = sha384.Hash;
// Transfer the first 24 characters of the
hashed value to the key
// and the remaining 8 characters to the
intialization vector.
for( int loop=0; loop<24; loop++ ) _Key[loop]
result[loop];
for( int loop=24; loop<40; loop++ ) _IV[loop-24]
= result[loop];
HttpContext context = HttpContext.Current;
ModuleSettings data
(ModuleSettings)context.Cache["Accounts_Settings"];
if (data == null)
{
XmlSerializer serializer = new
XmlSerializer(typeof(ModuleSettings));
try
{
string fileName
HttpContext.Current.Server.MapPath(GetSettingsFile());
fileName
fileName.Replace(".Config",".Encrypted.Config");
if(!File.Exists(fileName))
{
data
GetUnEncryptedSettings();
}
else
{
// create a filestream
to read the XML document
fs = new
FileStream(fileName, FileMode.Open);
// Create the crypto
objects
rijndael = new
RijndaelManaged();
rijndaelDecrypt
rijndael.CreateDecryptor(_Key,_IV);
decryptStream = new
CryptoStream(
fs,
rijndaelDecrypt, CryptoStreamMode.Read);
// use the Deserialize
method to retrieve the oject state
data
(ModuleSettings)serializer.Deserialize(decryptStream);
context.Cache.Insert("Accounts_Settings", data, new
CacheDependency(fileName));
}
}
finally
{
if( rijndael != null )
rijndael.Clear();
if( rijndaelDecrypt != null )
rijndaelDecrypt.Dispose();
if( fs != null ) fs.Close();
}
}
return data;
}
public static ModuleSettings GetUnEncryptedSettings()
{
HttpContext context = HttpContext.Current;
string fileName
HttpContext.Current.Server.MapPath(GetSettingsFile());
ModuleSettings data
(ModuleSettings)context.Cache["Accounts_Settings"];
if(data != null)
{
context.Cache.Remove("Accounts_Settings");
}
else
{
XmlSerializer serializer = new
XmlSerializer(typeof(ModuleSettings));
try
{
// create a filestream to read
the XML document
FileStream fs = new
FileStream(fileName, FileMode.Open);
// use the Deserialize method to
retrieve the oject state
data
(ModuleSettings)serializer.Deserialize(fs);
fs.Close();
}
catch (System.IO.FileNotFoundException)
{
// if the file is not found,
return a new empty class
data = new ModuleSettings();
}
}
SaveSettings(data);
fileName
fileName.Replace(".Config",".Encrypted.Config");
context.Cache.Insert("Accounts_Settings", data,
new CacheDependency(fileName));
return data;
}
public static void SaveSettings(ModuleSettings data)
{
string secretPhrase
ConfigurationSettings.AppSettings["SiteID"];
CryptoStream encryptStream = null; //
Stream used to encrypt
RijndaelManaged rijndael = null; //
Rijndael provider
ICryptoTransform rijndaelEncrypt = null; //
Encrypting object
FileStream fs = null; //
// Initialize internal values
byte[] _Key = new byte[24];
byte[] _IV = new byte[16];
// Perform a hash operation using the phrase.
This will
// generate a unique 32 character value to be
used as the key.
byte[] bytePhrase
Encoding.ASCII.GetBytes(secretPhrase);
SHA384Managed sha384 = new SHA384Managed();
sha384.ComputeHash(bytePhrase);
byte[] result = sha384.Hash;
// Transfer the first 24 characters of the
hashed value to the key
// and the remaining 8 characters to the
intialization vector.
for( int loop=0; loop<24; loop++ ) _Key[loop]
result[loop];
for( int loop=24; loop<40; loop++ ) _IV[loop-24]
= result[loop];
string fileName
HttpContext.Current.Server.MapPath(GetSettingsFile());
fileName
fileName.Replace(".Config",".Encrypted.Config");
XmlSerializer serializer = new XmlSerializer
(typeof(ModuleSettings));
try
{
// serialize the object
fs = new FileStream(fileName,
FileMode.Create);
// Create the crypto objects
rijndael = new RijndaelManaged();
rijndael.Key = _Key;
rijndael.IV = _IV;
rijndaelEncrypt
rijndael.CreateEncryptor();
encryptStream = new CryptoStream(
fs, rijndaelEncrypt,
CryptoStreamMode.Write);
serializer.Serialize(encryptStream,
data);
encryptStream.FlushFinalBlock();
}
finally
{
if( rijndael != null ) rijndael.Clear();
if( rijndaelEncrypt != null )
rijndaelEncrypt.Dispose();
if( fs != null ) fs.Close();
}
}
private static string GetSettingsFile()
{
HttpContext context = HttpContext.Current;
// get the file path from the cache
string filePath
(string)context.Cache["Accounts_SettingsFile"];
// if path is null, get it from web.config
if (filePath == null)
{
// retrieve the value
filePath=ConfigurationSettings.AppSettings["Accounts_SettingsFile"];
// save into the cache
context.Cache["Accounts_SettingsFile"]
filePath;
}
// return the path
return filePath;
}
}