Simple String Encryption and Decryption with C#

A look at implementing the cryptography object in C# for string encryption and decryption, useful for passwords or connection strings.

By Tim Trott | C# ASP.Net MVC | October 19, 2011
835 words, estimated reading time 3 minutes.

Due to bizarre and strange legal issues, we are unable to go into any detail regarding the actual techniques involved during the encryption process, however, we can use the classes provided by Microsoft to encrypt our data. We have an article which can give you an overview of how cryptography works which you may find interesting.

In this article, we will have a look at simple string encryption and decryption with a focus on saving encrypted connection strings in the web.config or app.config files.

There are two methods for encrypting data in the web.config. There is a manual way and an automatic way. To start with we will look at manually encrypting the connection string.

C#
string conStr = "Driver={SQL Native Client};Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;";

This is a typical connection string to a SQL server with a username and password. This is not the sort of information that should be accessible but stored like this it can be accessed by anyone who can view the C# source code (not the HTML source code sent to the browser unless a coding error includes it.)

It would be far better to encrypt this string so that it is meaningless without proper decryption. We can do this with a simple base64 encoding which will only be effective against a casual reader and is not secure, or we can implement one of the many encryption routines supported by .Net. In this example, we will use the DES method.

All of the encryption methods require binary data as an input and they all return binary data. When you are encrypting strings they will need to be converted to binary beforehand.

C#
/ The plain string to encrypt
string plaintextString = "This is an encryption test";

/ Binary representation of plain text string
byte[] plaintextBytes = (new UnicodeEncoding()).GetBytes(plaintextString);

Next, we need to create a memory stream to hold the result data and an encryption algorithm.

C#
/ Encrypt using DES
SymmetricAlgorithm sa = DES.Create();
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, sa.CreateEncryptor(), CryptoStreamMode.Write);
csEncrypt.Write(plaintextBytes, 0, plaintextBytes.Length);
csEncrypt.Close();
byte[] encryptedTextBytes = msEncrypt.ToArray();
msEncrypt.Close();

Where the encrypted data is now stored within encryptedTextBytes. Decryption is the reverse procedure using a decryption algorithm.

C#
MemoryStream msDecrypt = new MemoryStream(encryptedTextBytes);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, sa.CreateDecryptor(), CryptoStreamMode.Read);
byte[] decryptedTextBytes = new Byte[encryptedTextBytes.Length];
csDecrypt.Read(decryptedTextBytes, 0, encryptedTextBytes.Length);
csDecrypt.Close();
msDecrypt.Close();

string decryptedTextString = (new UnicodeEncoding()).GetString(decryptedTextBytes);

You can now use the encrypted text to store. Note: a password has not been used to encrypt this data, so it can still be decrypted using the machine hash key.

The best solution is to use the automatic section protection feature of .Net. This is done using a WebConfigurationManager and RsaProtectedConfigurationProvider and can protect the entire appsettings section.

C#
using System.Web.Configuration;

private void EncryptAppSettings()  
{
    Configuration objConfig = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
    AppSettingsSection objAppsettings = (AppSettingsSection)objConfig.GetSection("appSettings");
    if (!objAppsettings.SectionInformation.IsProtected)
    {
        objAppsettings.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
        objAppsettings.SectionInformation.ForceSave = true;
        objConfig.Save(ConfigurationSaveMode.Modified);
    }
}
C#
private void DecryptAppSettings()
{
    Configuration objConfig = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
    AppSettingsSection objAppsettings = (AppSettingsSection)objConfig.GetSection("appSettings");
    if (objAppsettings.SectionInformation.IsProtected)
    {
        objAppsettings.SectionInformation.UnprotectSection();
        objAppsettings.SectionInformation.ForceSave = true;
        objConfig.Save(ConfigurationSaveMode.Modified);
    }
}

This code will effectively encrypt the entire appSettings section to make it unviewable by people with access to the web server, but should not have access to the settings (i.e. server administrator). Below is a before and after shot of a protected appSettings section.

xml
<appSettings>
  <add key="connectionString" value="Driver={SQL Native Client};Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;"/>
  <add key="test" value="this is a test"/>
</appSettings>
xml
<appSettings configProtectionProvider="RsaProtectedConfigurationProvider">
  <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
   xmlns="http://www.w3.org/2001/04/xmlenc#">
   <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
   <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
    <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
     <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
     <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
      <KeyName>Rsa Key</KeyName>
     </KeyInfo>
     <CipherData>
      <CipherValue>lp1R3ya0BYL9yI/vNYCyErq78X9XPwzUz7GC2ZnZ2/ruo1ESA9cQY7Vy0wVt7u+lRWHZ7iW+nD8qZHW8xIktJNw5lg7bRUcqsCUmIUL0xUv8Miz/MwFR4kBtebk+JGaawzZQYUgW+UcEUW63nVF5J2ERqUDzoqR0GUlySC2tvh4=</CipherValue>
     </CipherData>
    </EncryptedKey>
   </KeyInfo>
   <CipherData>
    <CipherValue>wkE0pqLLPVEaA1s625vA8nmDlMmsDz0m+UOdJz/g+H+792RwrC9Z/XuufuKnff3W9ovkbNiGt8tBQmctqKkNkj0GXp53SAhmUq6AAy1tsXXBlBxiABIIE/POFlOlWVI3cmZte1b9q7SPRCw6Bh6oHS2GS91O1sGFZUd7SZxK7oiq5FtaQX+97kvhNWTSb6go1dsCoGYbPOUY4FIEvPvxppdR1QLDsJIEme1BiyCi3NcTUkWBfqmFWKCFzZgmZOkU2LjtBPAat9Cix9TEHqnInCYFmotUbBOsA/qk2YsbVSalbIwNDMCR7Q==</CipherValue>
   </CipherData>
  </EncryptedData>
</appSettings>

You can still use the appSettings as normal, the only change is the way the data is held within the file.

Was this article helpful to you?
 

Related ArticlesThese articles may also be of interest to you

CommentsShare your thoughts in the comments below

If you enjoyed reading this article, or it helped you in some way, all I ask in return is you leave a comment below or share this page with your friends. Thank you.

There are no comments yet. Why not get the discussion started?

We respect your privacy, and will not make your email public. Learn how your comment data is processed.