Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / database / SQL-Server / SQL-Server-2008

FIPS Encryption Algorithms and Implementation of AES in C# and SQL Server 2008

4.95/5 (8 votes)
2 Oct 2013CPOL6 min read 44.3K  
Implementation of AES in C# and SQL Server 2008.

FIPS Encryption Algorithms Details

FIPS PUB 140-2 Annexes

Annex A: Approved Security Functions (Draft 01-04-2011)

  1. Symmetric Key
    1. Advanced Encryption Standard (AES)
    2. Triple-DES Encryption Algorithm (TDEA)
    3. Escrowed Encryption Standard (EES)
  2. Asymmetric Key (DSS – DSA, RSA and ECDSA)
    1. Digital Signature Standard (DSS)
  3. Secure Hash Standard (SHS)
    1. Secure Hash Standard (SHS) (SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224 and SHA-512/256)
  4. Random Number Generators (RNG and DRBG)
    1. Annex C: Approved Random Number Generators
  5. Message Authentication (Triple-DES, AES and SHS)
    1. Triple-DES
    2. AES
    3. SHS

Annex B: Approved Protection Profiles (Draft 06-14-2007)

Annex B provides a list of the approved protection profiles applicable to FIPS PUB 140-2.

Annex C: Approved Random Number Generators (Draft 11-22-2010)

  1. Deterministic Random Number Generators
  2. Nondeterministic Random Number Generators

Annex D: Approved Key Establishment Techniques (Draft 01-04-2011)

  1. Key Establishment Techniques

Message Authentication (Triple-DES and AES)

Advance Encryption Standard (AES) and Triple DES (TDES or 3DES) are commonly used block ciphers. Whether you choose AES or 3DES depends on your needs.

Triple-DES

Since 3DES is based on DES algorithm talk about DES first. DES was developed in 1977 and it was carefully designed to work better in hardware than software. DES performs lots of bit manipulation in substitution and permutation boxes in each of 16 rounds. For example, switching bit 30 with 16 is much simpler in hardware than software. DES encrypts data in 64 bit block size and uses effectively a 56 bit key. 56 bit key space amounts to approximately 72 quadrillion possibilities. Even though it seems large but according to today’s computing power it is not sufficient and vulnerable to brute force attack. Therefore, DES could not keep up with advancement in technology and it is no longer appropriate for security.

Because DES was widely used at that time, the quick solution was to introduce 3DES which is secure enough for most purposes today. 3DES is a construction of applying DES three times in sequence. 3DES with three different keys (K1, K2 and K3) has effective key length is 168 bits (The use of three distinct key is recommended of 3DES.).  Another variation is called two-key (K1 and K3 is same) 3DES reduces the effective key size to 112 bits which is less secure.  Two-key 3DES is widely used in electronic payments industry. 3DES takes three times as much CPU power than compare with its predecessor which is significant performance hit.

AES

The Rijndael algorithm has been selected as the Advance Encryption Standard (AES) to replace 3DES. AES is modified version of Rijndael algorithm.  Advance Encryption Standard evaluation criteria among others was:

  • Security
  • Software and hardware performance
  • Suitability in restricted-space environments
  • Resistance to power analysis and other implementation attacks

Rijndael was submitted by Joan Daemen, and Vincent Rijmen. When considered together Rijndael’s combination of security, performance, efficiency, implement ability, and flexibility made it an appropriate selection for the AES.

By design AES is faster in software and works efficiently in hardware. It works fast even on small devices such as smart phones, smart cards etc. AES provides more security due to larger block size and longer keys.  AES uses 128 bit fixed block size and works with 128, 192 and 256 bit keys. Rijndael algorithm in general is flexible enough to work with key and block size of any multiple of 32 bit with minimum of128 bits and maximum of 256 bits.

 

Triple-DES

AES

Description

Triple Data Encryption Standard

Advanced Encryption Standard

Timeline

Standardized 1977

Official standard since 2001

Type of algorithm

Symmetric

Symmetric

Key size (in bits)

168

192

Speed

Low

High

Time to crack (assume a machine could try 255 keys per second - NIST)

4.6 billion years

149 trillion years

Resource consumption

Medium

Low

Implementation for ASE with C# .NET 4.5

C#
using System;
using System.IO;
using System.Security.Cryptography;
namespace Aes_Example
{
    class AesExample
    {
        public static void Main()
        {
            try
            {
                string original = "Here is some data to encrypt!";
                // Create a new instance of the AesCryptoServiceProvider 
                // class.  This generates a new key and initialization  
                // vector (IV). 
                using (AesCryptoServiceProvider myAes = new AesCryptoServiceProvider())
                {
                    // Encrypt the string to an array of bytes. 
                    byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);
                    // Decrypt the bytes to a string. 
                    string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);
                    //Display the original data and the decrypted data.
                    Console.WriteLine("Original:   {0}", original);
                    Console.WriteLine("Round Trip: {0}", roundtrip);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.Message);
            }
        }
        static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
        {
            // Check arguments. 
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");
            byte[] encrypted;
            // Create an AesCryptoServiceProvider object 
            // with the specified key and IV. 
            using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;
                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                // Create the streams used for encryption. 
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = 
                            new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }
            // Return the encrypted bytes from the memory stream. 
            return encrypted;
        }
        static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments. 
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");
            // Declare the string used to hold 
            // the decrypted text. 
            string plaintext = null;
            // Create an AesCryptoServiceProvider object 
            // with the specified key and IV. 
            using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;
                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                // Create the streams used for decryption. 
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = 
                            new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            // Read the decrypted bytes from the decrypting stream 
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
            return plaintext;
        }
    }
}

Implementation of AES in SQL Server 2008R2

Step 1: Create a Master Key

The database level cryptographic feature in SQL Server depends on a database master key. There can be one master key per database and has to be created manually by administrators because it is not created automatically during installation.

The database master key is a symmetric key used to protect the private keys of certificates and asymmetric keys that are present in the database.

By default master key is encrypted by using the Triple DES algorithm and a user-supplied password. This default can be changed by using the DROP ENCRYPTION BY SERVICE MASTER KEY option of ALTER MASTER KEY. A master key that is not encrypted by the service master key must be opened by using the OPEN MASTER KEY statement and a password.

SQL
CREATE MASTER KEY ENCRYPTION 
BY PASSWORD = '23987hxJ#KL95234Chinna';

PASSWORD --> Specifies a password with which to encrypt or decrypt the database master key. Password must meet the Windows password policy requirements of the computer that is running the instance of SQL Server.

Example:  Before creating Master Key Check if it already created or not; use the following query.

SQL
SELECT * FROM sys.symmetric_keys 
--WHERE symmetric_key_id = 101
GO
-- PASSWORD should meet the SQL Server BOX OS
-- Password policy
CREATE MASTER KEY ENCRYPTION
BY PASSWORD ='Password!2'
GO

Image 1

Step 2: Create Certificate

A certificate is a database level securable that follows the X.509 standard.

CREATE CERTIFICATE can also load a certificate from a file or assembly. This statement can also generate a key pair and create a self-signed certificate. Private keys generated by SQL Server are 1024 bits long. Private keys imported from an external source have a minimum length of 384 bits and a maximum length of 3,456 bits. The length of an imported private key must be an integer multiple of 64 bits.

SQL
CREATE CERTIFICATE Certificate_Password
ENCRYPTION BY PASSWORD = 'Password!2'
WITH SUBJECT = 'Password protection',
EXPIRY_DATE = '12/31/2099'
GO

Execute and check certificate creation

SQL
SELECT * FROM sys.certificates
GO

Image 2

Step 3: Create Symmetric Key

The symmetric key must be encrypted by using at least one of the following or multiple keys. Those are by Certificate or password or symmetric key or asymmetric key or Provider.

When a symmetric key is encrypted with a password instead of the public key of the database master key, the TRIPLE DES encryption algorithm is used. Because of this, keys that are created with a strong encryption algorithm, such as AES, are themselves secured by a weaker algorithm. There are many more options to create a symmetric key, but here I am showing one simple approach.

SQL
CREATE SYMMETRIC KEY System_password
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE Certificate_Password;
GO

Check the database how it is been created

SQL
SELECT * FROM sys.symmetric_keys
--WHERE symmetric_key_id = 256
GO

Image 3

Step 4: Encrypt Data

Now it is time to encrypt some test data and see how it works. To encrypt the data first we have to open the symmetric key and the use the Certificate to encrypt the data. Make sure to close the symmetric key.

If certificate is created with password then we'll need to use password to open the certificate.

SQL
OPEN SYMMETRIC KEY System_password
      DECRYPTION BY CERTIFICATE Certificate_Password WITH PASSWORD = 'Password!2';
            INSERT INTO UserDetails1 (Username, Password, FirstName, LastName)
            VALUES ('dnyaneshwarp',ENCRYPTBYKEY(KEY_GUID(N'System_password'), 
            'dnyaneshwarp@gmail.com'), 'Dnyaneshwar', 'Pawar')
CLOSE SYMMETRIC KEY System_password;
GO

Image 4

Step 5: Decrypt Data

Now we see how to decrypt the same data back to text. To decrypt the data first we have to open the symmetric key and the use the Certificate to encrypt the data. Make sure to close the symmetric key.

If certificate is created with password then we'll need to use password to open the certificate.

SQL
OPEN SYMMETRIC KEY System_password
DECRYPTION BY CERTIFICATE Certificate_Password WITH PASSWORD = 'Password!2';
      SELECT USERID, USERNAME, CAST(DECRYPTBYKEY([Password]) as varchar(200)) AS Password,
               FIRSTNAME, LASTNAME
      FROM UserDetails1
CLOSE SYMMETRIC KEY System_password;
GO

Image 5

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)