Click here to Skip to main content
15,885,366 members
Articles / Programming Languages / C#

The case for a channel-schema concept

Rate me:
Please Sign up or sign in to vote.
4.64/5 (10 votes)
17 May 2003CPOL9 min read 59.6K   623   24  
An article about .NET remoting channel schemas
// Stephen Toub
// stoub@microsoft.com
// CryptoHelper.cs

using System;
using System.IO;
using System.Security.Cryptography;

namespace MsdnMag.Remoting
{
	/// <summary>Helper functions for working with encryption and streams.</summary>
	public class CryptoHelper
	{
		#region Member Variables
		/// <summary>Size to use for byte buffers when performing IO.</summary>
		private const int _bufferSize = 2048;
		#endregion

		#region Construction
		/// <summary>Prevent external instantiation.  Class only has static helpers.</summary>
		private CryptoHelper() {}
		#endregion

		#region Creating Providers
		/// <summary>Factory for symmetric algorithm providers.  Creates a new provider by name.</summary>
		/// <param name="algorithm">The name of the algorithm to use (e.g. "DES")</param>
		/// <returns>A SymmetricAlgorithm provider to be used for communication
		/// between client and server.</returns>
		/// <remarks>Currently supports "DES", "3DES", "RIJNDAEL", and "RC2".</remarks>
		public static SymmetricAlgorithm GetNewSymmetricProvider(string algorithm)
		{
			// Return a provider based on the chosen algorithm
			switch(algorithm.Trim().ToLower())
			{
				case "3des": return new TripleDESCryptoServiceProvider();
				case "rijndael": return new RijndaelManaged();
				case "rc2": return new RC2CryptoServiceProvider();
				case "des": return new DESCryptoServiceProvider();
				default: throw new ArgumentException("Provider must be '3DES', 'DES', 'RIJNDAEL', or 'RC2'.", "algorithm");
			}
		}
		#endregion

		#region Encryption and Decryption Helpers
		/// <summary>
		/// Encrypts a stream with the specified symmetric provider.  The returned stream
		/// is at position zero and ready to be read.
		/// </summary>
		/// <param name="inStream">The stream to encrypt.</param>
		/// <param name="provider">The cryptographic provider to use for encryption.</param>
		/// <returns>Encrypted stream ready to be read.</returns>
		public static Stream GetEncryptedStream(Stream inStream, SymmetricAlgorithm provider) 
		{
			// Make sure we got valid input
			if (inStream == null) throw new ArgumentNullException("Invalid stream.", "inStream");
			if (provider == null) throw new ArgumentNullException("Invalid provider.", "provider");

			// Create the output stream
			MemoryStream outStream = new MemoryStream();
			CryptoStream encryptStream = new CryptoStream(outStream, provider.CreateEncryptor(), CryptoStreamMode.Write);

			// Encrypt the stream by reading all bytes from the input stream and
			// writing them to the output encryption stream.  Note that we're depending
			// on the fact that ~CryptoStream does not close the underlying stream.
			int numBytes;
			byte [] inputBytes = new byte[_bufferSize];
			while((numBytes = inStream.Read(inputBytes, 0, inputBytes.Length)) != 0) 
			{
				encryptStream.Write(inputBytes, 0, numBytes);
			}
			encryptStream.FlushFinalBlock();

			// Go back to the beginning of the newly encrypted stream and return it
			outStream.Position = 0;
			return outStream;
		}

		
		/// <summary>
		/// Decrypts a stream with the specified symmetric provider.
		/// </summary>
		/// <param name="inStream">The stream to decrypt.</param>
		/// <param name="provider">The cryptographic provider to use for encrypting.</param>
		/// <returns>Plaintext stream ready to be read.</returns>
		public static Stream GetDecryptedStream(Stream inStream, SymmetricAlgorithm provider) 
		{
			// Make sure we got valid input
			if (inStream == null) throw new ArgumentNullException("Invalid stream.", "inStream");
			if (provider == null) throw new ArgumentNullException("Invalid provider.", "provider");

			// Create the input and output streams
			CryptoStream decryptStream = new CryptoStream(inStream, provider.CreateDecryptor(), CryptoStreamMode.Read);
			MemoryStream outStream = new MemoryStream();
			
			// Read the stream and write it to the output. Note that we're depending
			// on the fact that ~CryptoStream does not close the underlying stream.
			int numBytes;
			byte [] inputBytes = new byte[_bufferSize];
			while((numBytes = decryptStream.Read(inputBytes, 0, inputBytes.Length)) != 0) 
			{
				outStream.Write(inputBytes, 0, numBytes);
			}

			// Go to the beginning of the decrypted stream and return it
			outStream.Position = 0;
			return outStream;
		}
		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Web Developer
United States United States
I am a consultant, trainer, software archtect/engineer, since the early 1980s, working in the greater area of Boston, MA, USA.

My work comprises the entire spectrum of software, shrink-wrapped applications, IT client-server, systems and protocol related work, compilers and operating systems, and more ....

I am currently focused on platform development for distributed computing in service oriented data centers.

Comments and Discussions