The transform method was designed to handle both encryption and decryption since symmetric algorithms are very similar in terms of how to encrypt and how to decrypt. That's one of the advantages of implementing symmetric encryption in your application. The example's Transform method was adopted from http://www.developer.com/net/vb/article.php/3077901 when the original implementation was written a couple of months ago. Since then, it was expanded to fit the mold a little better using C# and more of the System.Security.Crypography.TripleDESCryptoServiceProvider.
private byte[] Transform(byte[] inputvar, ICryptoTransform transform)
{
System.IO.MemoryStream stream =
new System.IO.MemoryStream(2048);
CryptoStream encryptstream =
new CryptoStream(stream, transform, CryptoStreamMode.Write);
encryptstream.Write(inputvar, 0, (int)inputvar.Length);
encryptstream.FlushFinalBlock();
stream.Position = 0;
byte[] returnvar;
returnvar = new byte[(int)stream.Length];
stream.Read(returnvar, 0, (int)returnvar.Length);
encryptstream.Close();
stream.Close();
encryptstream = null;
stream = null;
return returnvar;
}
The Transform method has two parameters that require a brief examination. As mentioned before, DES-based encryptions are byte encryptions and will alter bytes through the DES algorithm. The first parameter is a byte array holding the value that's to be transformed. The second parameter is the ICryptoTransform implementing class that we pass in via Encrypt or Decrypt. That's where most of the logic is and is a very important part of the processes. This method was set to a private declaration since it should only be used by the Encrypt or Decrypt methods. By making it public, it would defeat the purpose of having all the operations in a specific class or assembly, and it's also bad practice.
CryptoStream encryptstream =
new CryptoStream(stream, transform, CryptoStreamMode.Write);
The CryptoStream object is found in the System.Security.Cryptography namespace and is used in most encryption implementations. It requires three parameters: System.IO.Stream, ICryptoTransform, and CryptoStreamMode. The Stream object we use is the MemoryStream since the value of the parameter will be filled as the input byte array is fed in. The ICryptoTransform containing the algorithm instructions is passed in directly by the calling methods (Encrypt and Decrypt), and the CryptoStreamMode we use is Write. We use System.Security.Cryptography.CryptoStreamMode.Write because we want to write the outcome into the MemoryStream.
// Write the input array values into the crypto stream, and transform.
encryptstream.Write(inputvar, 0, (int)inputvar.Length);
encryptstream.FlushFinalBlock();
It's safe to assume many are shaking their heads thinking "lazy." We're using CryptoStream.Write to write the transformation into the stream. The first parameter is the byte array storing what's to be read into the CryptoStream. The next two are integer based indicating the start and how many to read and transform into the CryptoStream. We use the FlushFinalBlock method to clear the remaining space in the MemoryStream.
In English, we're sending in a byte array, telling it to get the first to last items, and destroy whatever is left of the stream after it's been filled with the transformed bytes.
stream.Position = 0;
byte[] returnvar;
returnvar = new byte[(int)stream.Length];
stream.Read(returnvar, 0, (int)returnvar.Length);
Next on the plate is to retrieve the output from the transformation. To achieve this, we first set the stream to rewind back to the beginning by setting the property Position to 0. We declare the output byte array (this can be declared at the beginning of the method if you prefer), and we set the output byte array to a new byte array with the size of the stream. Using the Read method, we read the stream into the byte array in a similar fashion as we wrote previously.
All that's left is to close the streams and return the output byte array.
This example is a fairly easy implementation and can be altered to meet your application's needs. The best bet is to avoid making the methods more complicated than they need to be. The .NET Framework offers a lot of high-level objects that will do most of the work for you. It's obvious that 90% of the time, a custom implementation can be faster by using lower-level objects. However, in the case of Cryptography, it's best to let the scientist do what they're good at, and let the programmers do what they're best at.