Appendix . How To: Create an Encryption Library

This How To describes how to create a generic encryption library that can be used to encrypt and decrypt data using the following algorithms:

  • DES (Digital Encryption Standard)

  • Triple DES

  • Rijndael

  • RC2

For an example application that uses the class library created in this How To, see "Appendix " in the Reference section of this book.

Requirements

The following items describe the recommended hardware, software, network infrastructure, skills and knowledge, and service packs you will need.

  • Microsoft® Windows® 2000 operating system

  • Microsoft Visual Studio® .NET development system

The procedures in this article also require that you have knowledge of the Microsoft Visual C#™ development tool.

Summary

This How To includes the following procedures:

  1. Create a C# Class Library

  2. Create a Console Test Application

Create a C# Class Library

This procedure creates a C# class library, which will provide encryption and decryption functionality.

To create a C# class library

  1. Start Visual Studio .NET and create a new C# Class Library project called Encryption.

  2. Use Solution Explorer to rename class1.cs as EncryptTransformer.cs.

  3. In EncryptTransformer.cs, rename Class1 as EncryptTransformer.

  4. Change the scope of the class from public to internal.

    internal class EncryptTransformer
  5. Add the following using statement at the top of the file.

    using System.Security.Cryptography;
  6. Add the following enumerated type within the Encryption namespace.

    public enum EncryptionAlgorithm {Des = 1, Rc2, Rijndael, TripleDes};
  7. Add the following private member variables to the EncryptTransformer class.

    private EncryptionAlgorithm algorithmID;
    private byte[] initVec;
    private byte[] encKey;
  8. Replace the default constructor with the following constructor.

    internal EncryptTransformer(EncryptionAlgorithm algId)
    {
      //Save the algorithm being used.
      algorithmID = algId;
    }
  9. Add the following method to the class.

    internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey)
    {
      // Pick the provider.
      switch (algorithmID)
      {
        case EncryptionAlgorithm.Des:
        {
          DES des = new DESCryptoServiceProvider();
          des.Mode = CipherMode.CBC;
          // See if a key was provided
          if (null == bytesKey)
          {
            encKey = des.Key;
          }
          else
          {
            des.Key = bytesKey;
            encKey = des.Key;
          }
          // See if the client provided an initialization vector
          if (null == initVec)
          { // Have the algorithm create one
            initVec = des.IV;
          }
          else
          { //No, give it to the algorithm
            des.IV = initVec;
          }
          return des.CreateEncryptor();
        }
        case EncryptionAlgorithm.TripleDes:
        {
          TripleDES des3 = new TripleDESCryptoServiceProvider();
          des3.Mode = CipherMode.CBC;
          // See if a key was provided
          if (null == bytesKey)
          {
            encKey = des3.Key;
          }
          else
          {
            des3.Key = bytesKey;
            encKey = des3.Key;
          }
          // See if the client provided an IV
          if (null == initVec)
          { //Yes, have the alg create one
            initVec = des3.IV;
          }
          else
          { //No, give it to the alg.
            des3.IV = initVec;
          }
          return des3.CreateEncryptor();
        }
        case EncryptionAlgorithm.Rc2:
        {
          RC2 rc2 = new RC2CryptoServiceProvider();
          rc2.Mode = CipherMode.CBC;
          // Test to see if a key was provided
          if (null == bytesKey)
          {
            encKey = rc2.Key;
          }
          else
          {
            rc2.Key = bytesKey;
            encKey = rc2.Key;
          }
          // See if the client provided an IV
          if (null == initVec)
          { //Yes, have the alg create one
            initVec = rc2.IV;
          }
          else
          { //No, give it to the alg.
            rc2.IV = initVec;
          }
          return rc2.CreateEncryptor();
        }
        case EncryptionAlgorithm.Rijndael:
        {
          Rijndael rijndael = new RijndaelManaged();
          rijndael.Mode = CipherMode.CBC;
          // Test to see if a key was provided
          if(null == bytesKey)
          {
            encKey = rijndael.Key;
          }
          else
          {
            rijndael.Key = bytesKey;
            encKey = rijndael.Key;
          }
          // See if the client provided an IV
          if(null == initVec)
          { //Yes, have the alg create one
            initVec = rijndael.IV;
          }
          else
          { //No, give it to the alg.
            rijndael.IV = initVec;
          }
          return rijndael.CreateEncryptor();
        }
        default:
        {
          throw new CryptographicException("Algorithm ID '" + algorithmID +
                                           "' not supported.");
        }
      }
    }
  10. Add the following properties to the class.

    internal byte[] IV
    {
      get{return initVec;}
      set{initVec = value;}
    }
    internal byte[] Key
    {
      get{return encKey;}
    }
  11. Add a new class called DecryptTransformer to the project.

  12. Add the following using statement at the top of the DecryptTransformer.cs file.

    using System.Security.Cryptography;
  13. Change the class scope from public to internal.

  14. Replace the default constructor with the following constructor.

    internal DecryptTransformer(EncryptionAlgorithm deCryptId)
    {
      algorithmID = deCryptId;
    }
  15. Add the following private variables to the class.

    private EncryptionAlgorithm algorithmID;
    private byte[] initVec;
  16. Add the following method to the class.

    internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey)
    {
      // Pick the provider.
      switch (algorithmID)
      {
        case EncryptionAlgorithm.Des:
        {
          DES des = new DESCryptoServiceProvider();
          des.Mode = CipherMode.CBC;
          des.Key = bytesKey;
          des.IV = initVec;
          return des.CreateDecryptor();
        }
        case EncryptionAlgorithm.TripleDes:
        {
          TripleDES des3 = new TripleDESCryptoServiceProvider();
          des3.Mode = CipherMode.CBC;
          return des3.CreateDecryptor(bytesKey, initVec);
        }
        case EncryptionAlgorithm.Rc2:
        {
          RC2 rc2 = new RC2CryptoServiceProvider();
          rc2.Mode = CipherMode.CBC;
          return rc2.CreateDecryptor(bytesKey, initVec);
        }
        case EncryptionAlgorithm.Rijndael:
        {
          Rijndael rijndael = new RijndaelManaged();
          rijndael.Mode = CipherMode.CBC;
          return rijndael.CreateDecryptor(bytesKey, initVec);
        }
        default:
        {
          throw new CryptographicException("Algorithm ID '" + algorithmID +
                                           "' not supported.");
        }
      }
    } //end GetCryptoServiceProvider
  17. Add the following property to the class.

    internal byte[] IV
    {
      set{initVec = value;}
    }
  18. Add a new class called Encryptor to the project.

  19. Add the following using statements at the top of Encryptor.cs.

    using System.Security.Cryptography;
    using System.IO;
  20. Replace the default constructor with the following constructor.

    public Encryptor(EncryptionAlgorithm algId)
    {
      transformer = new EncryptTransformer(algId);
    }
  21. Add the following private member variables to the class.

    private EncryptTransformer transformer;
    private byte[] initVec;
    private byte[] encKey;
  22. Add the following Encrypt method to the class.

    public byte[] Encrypt(byte[] bytesData, byte[] bytesKey)
    {
      //Set up the stream that will hold the encrypted data.
      MemoryStream memStreamEncryptedData = new MemoryStream();
    
      transformer.IV = initVec;
      ICryptoTransform transform = transformer.GetCryptoServiceProvider(bytesKey);
      CryptoStream encStream = new CryptoStream(memStreamEncryptedData,
                                                transform,
                                                CryptoStreamMode.Write);
      try
      {
        //Encrypt the data, write it to the memory stream.
        encStream.Write(bytesData, 0, bytesData.Length);
      }
      catch(Exception ex)
      {
        throw new Exception("Error while writing encrypted data to the stream: 
    "
                            + ex.Message);
      }
      //Set the IV and key for the client to retrieve
      encKey = transformer.Key;
      initVec = transformer.IV;
      encStream.FlushFinalBlock();
      encStream.Close();
    
      //Send the data back.
      return memStreamEncryptedData.ToArray();
    }//end Encrypt
  23. Add the following properties to the class.

    public byte[] IV
    {
      get{return initVec;}
      set{initVec = value;}
    }
    
    public byte[] Key
    {
      get{return encKey;}
    }
  24. Add a new class called Decryptor to the project.

  25. Add the following using statements at the top of Decryptor.cs

    using System.Security.Cryptography;
    using System.IO;
  26. Replace the default constructor with the following constructor.

    public Decryptor(EncryptionAlgorithm algId)
    {
      transformer = new DecryptTransformer(algId);
    }
  27. Add the following private member variables to the class.

    private DecryptTransformer transformer;
    private byte[] initVec;
  28. Add the following Decrypt method to the class.

    public byte[] Decrypt(byte[] bytesData, byte[] bytesKey)
    {
      //Set up the memory stream for the decrypted data.
      MemoryStream memStreamDecryptedData = new MemoryStream();
    
      //Pass in the initialization vector.
      transformer.IV = initVec;
      ICryptoTransform transform = transformer.GetCryptoServiceProvider(bytesKey);
      CryptoStream decStream = new CryptoStream(memStreamDecryptedData,
                                                transform,
                                                CryptoStreamMode.Write);
      try
      {
        decStream.Write(bytesData, 0, bytesData.Length);
      }
      catch(Exception ex)
      {
        throw new Exception("Error while writing encrypted data to the stream: 
    "
                            + ex.Message);
      }
      decStream.FlushFinalBlock();
      decStream.Close();
      // Send the data back.
      return memStreamDecryptedData.ToArray();
    } //end Decrypt
  29. Add the following property to the class.

    public byte[] IV
    {
      set{initVec = value;}
    }
  30. On the Build menu, click Build Solution.

Create a Console Test Application

This procedure creates a simple console test application to test the encryption and decryption functionality.

To create a console test application

  1. Add a new C# Console application called EncryptionTester to the current solution.

  2. In Solution Explorer, right-click the EncryptionTester project, and then click Set as StartUp Project.

  3. Use Solution Explorer to rename class1.cs as EncryptionTest.cs.

  4. In EncryptionTest.cs, rename Class1 as EncryptionTest.

  5. Add a project reference to the Encryption project.

  6. Add the following using statements at the top of EncryptionTest.cs.

    using System.Text;
    using Encryption;
  7. Add the following code to the Main method.

    // Set the required algorithm
    EncryptionAlgorithm algorithm = EncryptionAlgorithm.Des;
    
    // Init variables.
    byte[] IV = null;
    byte[] cipherText = null;
    byte[] key = null;
    
    try
    { //Try to encrypt.
      //Create the encryptor.
      Encryptor enc = new Encryptor(EncryptionAlgorithm.Des);
      byte[] plainText = Encoding.ASCII.GetBytes("Test String");
    
      if ((EncryptionAlgorithm.TripleDes == algorithm) ||
          (EncryptionAlgorithm.Rijndael == algorithm))
      { //3Des only work with a 16 or 24 byte key.
        key = Encoding.ASCII.GetBytes("password12345678");
        if (EncryptionAlgorithm.Rijndael == algorithm)
        { // Must be 16 bytes for Rijndael.
          IV = Encoding.ASCII.GetBytes("init vec is big.");
        }
        else
        {
          IV = Encoding.ASCII.GetBytes("init vec");
        }
      }
      else
      { //Des only works with an 8 byte key. The others uses variable length keys.
        //Set the key to null to have a new one generated.
        key = Encoding.ASCII.GetBytes("password");
        IV = Encoding.ASCII.GetBytes("init vec");
      }
      // Uncomment the next lines to have the key or IV generated for you.
      // key = null;
      // IV = null;
    
      enc.IV = IV;
    
      // Perform the encryption.
      cipherText = enc.Encrypt(plainText, key);
      // Retrieve the intialization vector and key. You will need it
      // for decryption.
      IV = enc.IV;
      key = enc.Key;
    
      // Look at your cipher text and initialization vector.
      Console.WriteLine("          Cipher text: " +
                        Convert.ToBase64String(cipherText));
      Console.WriteLine("Initialization vector: " + Convert.ToBase64String(IV));
      Console.WriteLine("                  Key: " + Convert.ToBase64String(key));
    }
    catch(Exception ex)
    {
      Console.WriteLine("Exception encrypting. " + ex.Message);
      return;
    }
    try
    { //Try to decrypt.
      //Set up your decryption, give it the algorithm and initialization vector.
      Decryptor dec = new Decryptor(algorithm);
      dec.IV = IV;
      // Go ahead and decrypt.
      byte[] plainText = dec.Decrypt(cipherText, key);
      // Look at your plain text.
      Console.WriteLine("           Plain text: " +
                        Encoding.ASCII.GetString(plainText));
    }
    catch(Exception ex)
    {
      Console.WriteLine("Exception decrypting. " + ex.Message);
      return;
    }
  8. On the Build menu, click Build Solution.

  9. Run the test application to verify the operation of the Encryptor and Decryptor classes.

References

For more information, see "Appendix " in the Reference section of this book.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.93.175