Password Based Encryption using AES - PBKDF2

Password based Key Derivation Function 2 or PBKDF2 in short, is an encryption mechanism, which basically uses a password and manipulates it to generate a strong key which could be used for encryption and subsequently decryption. This article basically focusses on the .Net classes available to enable this and the use of AES encryption Algorithm to work with PBKDF2.

To generate the PBKDF2 password you need the following:

1. Pseudorandom function
.Net provide the Rfc2898DerviceBytes class which is Pseudorandom function generator based on HMCSHA1. The Rfc2898DerviceBytes takes your salt value, the password and an iteration number as inputs, to generate your PBKDF2 key.

2. Salt
This can be any random data. One random number generator which is crypto based and can come handy in generating Salt is the RNGCryptoServiceProvider class.

3. Iterations
This is the number of times the function repeats to generate the key. The higher the number the more secure the key is. But this brings some performance implications and hence you have to identify a number (preferably in thousands) which ensures maximum security with minimal performance cost for your application. It is also preferable to keep this as a random number rather than multiples of 1000 or 100. This is because during decryption you will have to recreate the password-based encryption key and have to use the same number of iterations. Hence the more random the number is, the more difficult it would be identify it and hence more secure your data.

Below code explains the use of Rfc2898DeriveBytes with AES encryption.

        var encryptor = Aes.create();
        var pdb = new Rfc2898DeriveBytes(passphrase, salt, iterations);
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV= pdb.GetBytes(16); 
        var memoryStream = new MemoryStream();
        var cryptoStream = new CryptoStream(memoryStream, encryptor.CreateEncryptor(),                                                                                      CryptoStreamMode.Write);
        var  dataBytes = new Encoding.Unicode.GetBytes("String to be encrypted");
        cryptoStream.Write(dataBytes, 0, dataBytes.Length);
        cryptoStream.Close();
       
       var encryptedText = Convert.ToBase64String(memoryStream.ToArray());

As you can see in the example I have used the same pdb object to generate not just the key but also the vector. This is particularly helpful when you need to decrypt and have no mechanism to store vector or password.

Hope this helps your work!