Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

The case for a channel-schema concept

, 17 May 2003
An article about .NET remoting channel schemas
channel-schema_src.zip
Channel Schema Solution
Channel Schema Solution.suo
InterfaceLibrary
App.ico
InterfaceLibrary.csproj.user
RemotingClient
App.ico
RemotingClient.csproj.user
RemotingServer
App.ico
RemotingServer.csproj.user
SecureChannel
SecureChannel.csproj.user
SecureChannelC#.snk
TestLibrary
TestLibrary.csproj.user
TwoWayChannel
TwoWayChannel.csproj.user
// 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)

About the Author

Wytek Szymanski
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.

| Advertise | Privacy | Mobile
Web03 | 2.8.140718.1 | Last Updated 18 May 2003
Article Copyright 2003 by Wytek Szymanski
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid