Encryption and Decryption in .NET

Not all information should be carelessly thrown about the internet.  Bits of information can be re-created easily .  So, what if we don't want the world to have access? Time to put on our cryptographer hats!  Here are some things I learned about encrypting and decrypting plain-text in .NET.  

To summarize briefly... encryption (aka the "cipher" process) involves moving or shifting bytes around in a specific algorithm so as to make the original meaning unknown.  Decryption uses the same algorithm to re-create the original text.

Security Standards

Many examples for .NET security use a special .NET class called Rijndael.  What a strange name, and what is it exactly? Well, it is the cipher behind the current Advanced Encryption Standard (AES).  The name is simply a combination of the names of the two cryptographers who created it, Vincent Rijmen and Joan Daemen.

"The AES cipher is specified as a number of repetitions of transformation rounds that convert the input plaintext into the final output of ciphertext"... and it is approved for "top secret" information.

Rijndael is a symmetric key algorithm, meaning the same "key" is used to create and decipher the information.

Rijndael in .NET

The .NET framework has its own implementation of Rijndael and it is found in the System.Security.Cryptography namespace.  MSDN page on Rijndael Managed. The class has to methods which create encryption and decryption classes... CreateEncryptor() and CreateDecryptor().  These must be called with the proper key and initialization vector (IV).

Here is sample code for Encryption...

            RijndaelManaged aesAlg = null;
            try
            {
                aesAlg = new RijndaelManaged();
                aesAlg.BlockSize = 128;         // 128 (for AES), 192 and 256 (Rijndael only), default = 128
                aesAlg.Padding = PaddingMode.PKCS7;
                aesAlg.KeySize = keySize;       // 128, 192, or 256; Key size must be set BEFORE actual Key
                aesAlg.Key = key;               // Secret Key
                aesAlg.IV = iv;                 // Initialization Vector (bit length must match BlockSize)

                // create a decryptor
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(key, iv);

                // create streams used for encryption
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (BinaryReader rdr = new BinaryReader(csDecrypt))
                        {
                            result = rdr.ReadBytes(cipherText.Length);
                        }
                    }
                }
            }
            finally
            {
                if (aesAlg != null)
                    aesAlg.Dispose();
            }

I have hard-coded some values for clarity. The BlockSize defaults to 128 bits. Rijndael does support sizes of 192 or 256, but these are not included in the actual AES standard as mentioned here.

The padding mode determines how extra bits are filled in, and the library's default is PKCS7

The KeySize can be set to 128, 192, or 256 bits, and it must be set BEFORE you set the Key

The Initialization Vector (IV) is a random string which must be the same length (in bits) as the BlockSize

A Unique Key

In order to create a unique key to pass to the CreateEncryptor and CreateDecryptor methods, you can use the PasswordDeriveBytes class. This class will generate a unique key based on a password and salt. This is done through its CryptDeriveKey method. But this method requires the name of the cryptography algorithm.

If the CryptDeriveKey method does not work for you, such as the case with Rijndael, you can use the GetBytes method instead.

                PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwdBytes, saltBytes, hashType, iterations);

                // For other encryption algorithms, pdb.CryptDeriveKey() is preferred instead of GetBytes(length), 
                // but I could not get this to work with Rijndael

                // Use the password to generate pseudo-random bytes for the encryption
                // key. Specify the size of the key in bytes (instead of bits).
                result = pdb.GetBytes(keyLength / 8);

Here is a link to a sample Visual Studio 2010 windows form project. Unzip, open in VS 2010 and hit F5.

BasicEncryption.zip (66.20 kb)

Tags:

 

SQL Server Sample Databases

On occasion, I have downloaded a sample project for Visual Studio which requires a reference to a sample database.  Of course, I never have that database installed, so I have to go on a hunt to find the database creation files.

The two most common samples I come across are the Northwind database (old sample for Sql Server 200) and the AdventureWorks database (sample for Sql Server 2008). If you need to install one of these sample db's, you can find them all on this CodePlex project...

Microsoft SqlServer Community Projects and Product Samples (databases and sample projects)

and

Microsoft SqlServer Database Product Samples (just the databases)

Tags:

 

.NET Framework SDK

I typically only access the Windows SDK on an as needed basis.  In ASP.NET development I have run rools such as aspnet_regsql.exe to create database tables for built-in providers like the ASP.NET Membership Provider.

When working with XML, the xsd.exe tool has been useful in the past for creating C# objects from .xsd schema files (but now I use XSDObjGen.exe).

Today, I got curious and began looking through all the other tools offered as part of the SDK.  Some others I found are

TcpAnalyzer.exe - shows all network communication with your pc.
WinDiff.exe - file comparison tool.. granted there are better tools out there.
WSDL.exe - generates code for web services.
MakeCert.exe - for creating x509 (SSL) certificates
SqlMetal.exe - creates code files from database tables, views, and procedures

These are just a few that I thought were interesting, but a full list can be found on the MSDN site...
.NET Framework Tools

On Windows, the SDK is located at C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin

 

Tags:

 

Three Parts to Every Dev Project

I think there are three main components to every coding project.... application, logging, and reporting.

Of course you have to have the application code, but why do we often leave off the other two?  It seems that even the smallest of projects require some level of logging/reporting, yet we often leave these off.  

Not having some basic logging features will result in poor debugging later because you can't trace a problem.  You don't have to log every little thing, but just enough to help locate a problem should something come up.

Reporting... eventually, someone will ask "how many times did... " or "what is the percentage of...".  Add a basic reporting mechanism to your application, so that you can, at least, answer the big questions.

For small applications, I have begun making a habit of using simple XML files to keep track of logging and reporting info.  It doesn't have to be complicated, in fact, the simpler the better.  A simple solution is likely to get used more!

Tags: