Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Deriving Encryption Keys From Passwords

0.00/5 (No votes)
25 Jul 2005 1  
Show how to generate and store your keys for cryptography in safe mode

Introduction

This article shows you how you can derive secure and strong keys for encryption in symmetric algorithms.

I assume you have knowledge on cryptography. You can read a good introductory article on encryption here.

Deriving a Key from a Password

Suppose you want to encrypt sensitive information of users of your application. You don't want anybody to be able to decrypt this data. So you decide to encrypt using Rijndael, a good symmetric algorithm. But Rijndael needs at least a 128 bit key. You also want to store this key in a secure environment.

I have written a complementary class to the EncDec described in this article.

This class generates Keys and IV, derives them from passwords, and stores them in a secure manner.

Here is the full implementation:

using System.Security.Cryptography;
public sealed class GenKeys
{
   /// <summary>
   /// Derive a key suitable for use in symmetric algorithms.
   /// </summary>
   /// <param name="password">a password in plain text, perhaps an easy
   /// to remember one
   /// </param>
   /// <param name="size">The size in BITS of the key</param>
   /// <returns>A key for use in encryption</returns>
   public static byte[] DeriveKeyFromPassword(string password, int size)
   {
      return DeriveKey(password, GenSalt(8), size/8);
   }

   /// <summary>
   /// Generate an IV (Initialization Vector) for use in Rijndael crypto
   /// algorithm
   /// </summary>
   /// <param name="size">size in bits of the vector</param>
   /// <returns>a new array o bytes with a random generated IV</returns>
   public byte[] GenIV(int size)
   {
      return GenSalt(size/8);
   }

    /// <summary>
    /// Generate a salt array, this is a vector of bytes used for the
    /// generation of strong keys.
    /// This method is used internally by DeriveKeyFromPassword()
    /// </summary>
    /// <param name="size">Size in bytes (watch out)</param>
    /// <returns>an array of random bytes of size bytes</returns>
    private static byte[] GenSalt(int size)
    {
      /// Use a cryptographic random number generator
      RandomNumberGenerator rng = RandomNumberGenerator.Create();
      // create the result array and fill it with non-zero bytes
      byte[] result = new byte[size];
      rng.GetNonZeroBytes (result);
      return result;
    }

    /// <summary>
    /// Derive a key form a password. This internally used by DeriveKeyFromPassword
    /// This is an advanced implementation, when you know how to generate
    /// a salt array
    /// </summary>
    /// <param name="password">A password, perhaps human readable and
    /// easy to remember </param>
    /// <param name="salt">A salt array used to generate a password</param>
    /// <param name="size">the size in bytes of the key</param>
    /// <returns>a key of size bytes</returns>
    private static byte[] DeriveKey(string password, byte[] salt, int size)
    {
        PasswordDeriveBytes pder = new PasswordDeriveBytes(password, salt);
        pder.IterationCount = 100;
        pder.HashName = "SHA1";
        return pder.GetBytes (size);
     }
}

Now you can use this class with EncDec in this way:

byte[] iv = GenKeys.GenIV(128);
byte[] key = GenKeys.DeriveKeyFromPassword("my own private password", 128);
byte[] data = {......};
EncDec.Encrypt(data, key, iv) 

EncDec has methods that use PasswordDerivedBytes class, but in the implementation, the salt is hard coded. Using GenKeys class, you can generate and store the keys outside your program.

One trick is to use an automatic generated password, for example the MAC address of your Ethernet card and use it for deriving a password, then generate the IV deriving from another automatically generated, like the CPU ID, size of your executable, the primary Key of a record in a table, etc.

The Search of a Secure Key Storage

I will start writing in my blog about this topic, and I will investigate ways to store the generated keys in a safe manner.

I will update this article when my investigations give acceptable results.

See you soon.

Visit my blog here.

History

  • 25th July, 2005: Initial post

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