Click here to Skip to main content
15,867,453 members
Articles / Web Development / ASP.NET
Article

TripleDES Encrypted Configuration File

Rate me:
Please Sign up or sign in to vote.
4.41/5 (15 votes)
29 Feb 20043 min read 94.8K   4.5K   62   10
How to make your server settings safer

Sample Image - screenshot.png

Introduction

I didn't want plain text configuration files for my production SQL server, I wanted those blocks encrypted with TripleDES. So, what I decided to do was create a class that could read and write configuration files with both plain and encrypted text. (For use in an ASP.NET app).

Updates

2/29/04:
A security hole has been patched where you could see the Private key code using a reflection utility. Now, you can still see the variable decleration but you can not see its value. The source code and demo projects have been updated.

3/1/04:
A security fix to the file names extention was made to prevent the settings.config file from being downloaded. I have also included batch files for commandline compileing.

Problems with security

The only drawback (or good point, depending how you look at it) is that to change the private key the source code has to be changed and recompiled. All the encrypted items that are written out by the program have their own unique public key for maximum security. Lets look at a file:

XML
<appSettings>
  <add key="ownersName" value="Matthew" />
  <add key="emailServer" value="FRAGPDC" />
  <add key="sqlServer" value="FRAGPDC" />
  <add key="sqlUser" encode="90lIn5/qBsY=" value="Dk3fxrNRfvM=" />
  <add key="sqlPassword" encode="YRG9vvfk9m0=" 
       value="SrczFf67nLlL0XgJjfm3gQ==" />
</appSettings>

As you can see not every line is encrypted only the ones that require extra security are encrypted TripleDES. On the lines that are encrypted the [encode] attribute is the public key for that item. The private key is safely tucked away in the compiled DLL.

Reading the data

It is very easy to Read or Display the data using the getSetting method.

C#
Configure.getSetting(key);

key is the name of the key you want from the settings file. If there is no key by that name in the settings file then an empty string will be returned.

Writing the data

Its just as easy to write the data, all you need to do is use the writeSetting method.

C#
Write an encrypted string:
Configure.writeSetting(thisKey, Request.Form[thisKey], true);


Write a text string:
Configure.writeSetting(thisKey, Request.Form[thisKey], false);

thisKey is the name of the key, Request.Form[thisKey] is the value of the key and the true or false is if you want encryption.

Changing the private key

I have included a program that when run will generate a new random key. Here is some sample output:

Image 2

Next you need to change this line in the source code:

Image 3

Code

The code in the keyGeneration app is very much similar to the code in the DLL so lets take a look at it. First we have to tell the app what classes we want to use. The System.Text class will provide character encoding services and System.Security.Cryptography is where the algorithms for the encryption are stored.

C#
using System;
using System.Text;

using System.Security.Cryptography;


class MainClass
{
    public static TripleDESCryptoServiceProvider des = 
                                     new TripleDESCryptoServiceProvider(); 

Tto encode and decode the string we have two functions:

C#
private static string encode(string thisEncode)
{
    string encrypted;
    byte[] Code = ASCIIEncoding.ASCII.GetBytes(thisEncode);

    encrypted = Convert.ToBase64String(
            des.CreateEncryptor().TransformFinalBlock(Code, 0,
                                                      Code.Length)
  );

    return encrypted;
}


private static string decode(string thisDecode)
{
    string decrypted;
    byte[] Code = Convert.FromBase64String(thisDecode);

    decrypted = ASCIIEncoding.ASCII.GetString(
            des.CreateDecryptor().TransformFinalBlock(Code, 0,
                                                      Code.Length)
  );

    return decrypted;
}

Here is the main block of code to tie it together:

C#
public static void Main(string[] args)
{
    des.GenerateIV();
    des.GenerateKey();

    Console.WriteLine("New Key");
    Console.WriteLine("You only need to cut and paste the private key " +
                      "into the source");
    Console.WriteLine();

    Console.WriteLine(" Public: {0}", Convert.ToBase64String(des.IV));
    Console.WriteLine("Private: {0}", Convert.ToBase64String(des.Key));
    Console.WriteLine();

    string encoded = encode("[Triple DES] This is an encoded string");

    Console.WriteLine("Encoded: {0}", encoded);
    Console.WriteLine("Decoded: {0}", decode(encoded));
    Console.WriteLine();
    Console.Write("Press return to exit...");
    Console.ReadLine();
}

The web Page

Basically this is just a standard aspx web page that imports the namespace of the dll and gathers its information on the PostBack event.

ASP.NET
<%@ Page language="c#" %>
<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="appSettings.Settings" %>

<script runat="server">
        private void Page_Load(object sender, System.EventArgs e)
        {
            if (this.IsPostBack) 
            {
                foreach (string thisKey in Request.Form.AllKeys) 
                {
                    if (thisKey != "__VIEWSTATE") 
                        if ((thisKey == "databasePassword") || 
                            (thisKey == "databaseUser"))
                        {
                            Configure.writeSetting(thisKey, 
                                                Request.Form[thisKey], true);
                        }
                        else
                        {
                            Configure.writeSetting(thisKey, 
                                                Request.Form[thisKey], false);
                        }
                }
            }
        }
</script>

<HTML>
    <HEAD>
        <title>Setup</title>
        <link rel="stylesheet" type="text/css" href="setup.css" />
    </HEAD>
    <body>
        <form id="appSettings" method="post" runat="server">
        <div id="content">
            <div class="title">Database Server Settings<hr></div>

            <div class="smallTab" id="text">Database Server:</div>
            <div class="bigTab"><input type=text name="databaseServer" 
                    value="<%= Configure.getSetting("databaseServer") %>" 
                  size=30></div>

            <div class="smallTab" id="text">Database User:</div>
            <div class="bigTab"><input type=text name="databaseUser" 
                    value="<%= Configure.getSetting("databaseUser") %>" 
                  size=30></div>

            <div class="smallTab" id="text">Database Name:</div>
            <div class="bigTab"><input type=text name="databaseName" 
                    value="<%= Configure.getSetting("databaseName") %>"  
                  size=30></div>

            <div class="smallTab" id="text">Database Password:</div>
            <div class="bigTab"><input type=password name="databasePassword" 
                    value="<%= Configure.getSetting("databasePassword") %>"  
                  size=30></div>

            <div align="center"><input type="submit" value=" Update Database 
                   Settings "></div>
        </div>
        </form>
    </body>
</HTML>

To install the web page just uncompress the configure_demo.zip into an empty directory under the wwwroot tree.
IMPORTANT: Don't forget to go into the internet control panel and set this directory as an application otherwise the DLL won't be found!

Permissions

For security reasons I didn't write this to the web.config file, its written to settings.config. Now if the ASPNET service (Who your webserver runs as) creates this file the permissions will be fine. But if you create this file you will need to give the ASPNET user access to write to the file. Also if you go in and edit the file later by hand you will need to reset the permissions. You have been warned :-)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
I started programming for fun when I was about 10 on an Franklin Ace 1000.

I still do it just for fun but it has gotten me a few jobs over the years. More then I can say for my Microsoft Certifications. Smile | :)

The way I learned was by example, now its time to give back to the next generation of coders.



Comments and Discussions

 
Generalpublic key reference in your article Pin
Steve Bansleben25-Aug-04 8:58
sussSteve Bansleben25-Aug-04 8:58 
Matthew,

It is very confusing to mention the word public in your article about a 'private' symmetric key encryption method such as TripleDES. This should be reserved for PKI discussions.

Steve Bansleben
GeneralDon't .xml file extension! Pin
JimHugh1-Mar-04 2:37
JimHugh1-Mar-04 2:37 
GeneralRe: Don't .xml file extension! Pin
Matthew Hazlett1-Mar-04 8:17
Matthew Hazlett1-Mar-04 8:17 
GeneralRe: Don't .xml file extension! Pin
Matthew Hazlett1-Mar-04 9:33
Matthew Hazlett1-Mar-04 9:33 
GeneralHave a look Pin
MrEyes1-Mar-04 0:32
MrEyes1-Mar-04 0:32 
GeneralBetter to use DPAPI Pin
Ohad Israeli29-Feb-04 19:40
Ohad Israeli29-Feb-04 19:40 
GeneralRe: Better to use DPAPI Pin
Matthew Hazlett29-Feb-04 20:06
Matthew Hazlett29-Feb-04 20:06 
GeneralRe: Better to use DPAPI Pin
Matthew Hazlett29-Feb-04 20:32
Matthew Hazlett29-Feb-04 20:32 
GeneralRe: Better to use DPAPI Pin
Richard Deeming10-Mar-04 6:44
mveRichard Deeming10-Mar-04 6:44 
GeneralRe: Better to use DPAPI Pin
Matthew Hazlett10-Mar-04 7:15
Matthew Hazlett10-Mar-04 7:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.