A while back I posted a question concerning a custom Cryptography class (C#) I compiled using the four .NET supported symmetric algorithms (DES, RC2, Rijndael, TripleDES).
I have tentatively "finished" the class and wanted to post it here for comments, feedback, distribution, whatever. Feel free to take the class, use it, modify it, do whatever you will with it. It encrypts/decrypts strings and files, hashes encryption keys (if desired), overloaded constructors, enumerations, etc. I've got it fairly thoroughly commented as well, so it's easy to use if Intellisense is enabled.
If there are things that can be updated, added, modified, please let me know. If this class is helpful at all, please post and let me know.
By the way, if any stupid emoticons show up, you might have to check the HTML source to verify what the actual source is at that poinit.
/********************************************************************/
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace
{
///
/// The CryptoSymmetric class utilizes the System.Security.Cryptography to provide
/// cryptographic methods on strings and files. The CryptoSymmetric class
/// allows the use of four symmetric algorithms : DES, RC2, Rijndael, and TripleDES.
///
public class CryptoSymmetric
{
#region Class Enumerations
///
/// Enumeration of supported symmetric algorithms.
///
public enum CryptoAlgorithm : int
{
DES, RC2, Rijndael, TripleDES
}
///
/// Enumeration of supported hash algorithms.
/// The Hash algorithm is used to hash the Key before encyrption/decryption.
///
public enum HashAlgorithm : int
{
MD5, SHA1, SHA256, SHA384, SHA512, None
}
///
/// Enumeration to designate whether encryption or decryption is the
/// desired transformation.
///
private enum CryptoMethod
{
Encrypt, Decrypt
}
#endregion
#region Properties
///
/// The key used for encryption/decryption.
///
private byte[] bytesKey;
///
/// The initialization vector used for encryption/decryption.
///
private byte[] bytesIV;
///
/// The symmetric algorithm service provider for encryption/decryption.
///
private SymmetricAlgorithm objCryptoService;
///
/// The symmetric algorithm for encryption/decryption.
///
private CryptoAlgorithm algorithmID;
///
/// The hash algorithm for hashing the key.
///
private HashAlgorithm hashID;
#endregion
#region Accessor Methods
///
/// Gets or sets the encryption Key
///
public byte[] Key
{
get
{
return bytesKey;
}
set
{
// if they set this via the accessor, make sure it's legal
bytesKey = GetLegalKey(value);
}
}
///
/// Gets or sets the Initialization Vector
///
public byte[] IV
{
get
{
return bytesIV;
}
set
{
// if they set this via the accessor, make sure it's valid
bytesIV = GetValidIV(value);
}
}
///
/// Gets or sets the CryptoAlgorithm type
///
public CryptoAlgorithm EncryptionAlgorithm
{
get
{
return algorithmID;
}
set
{
algorithmID = value;
}
}
///
/// Gets or sets the Hash Algorithm type
///
public HashAlgorithm HashType
{
get
{
return hashID;
}
set
{
hashID = value;
}
}
#endregion
#region Constructors
///
/// Initializes an instance of the CryptoSymmetric class.
///
public CryptoSymmetric(CryptoAlgorithm crypto)
{
// call our base constructor
__CryptoSymmetric(crypto, HashAlgorithm.None);
}
///
/// Initializes an instance of the CryptoSymmetric class.
///
public CryptoSymmetric(CryptoAlgorithm crypto, string Key)
{
// initialize the encryption Key and use Key as IV
bytesKey = GetLegalKey(Key);
bytesIV = GetValidIV(Key);
// call our base constructor
__CryptoSymmetric(crypto, HashAlgorithm.None);
}
///
/// Initializes an instance of the CryptoSymmetric class.
///
public CryptoSymmetric(CryptoAlgorithm crypto, string Key, string IV)
{
// initialize the encryption Key, IV
bytesKey = GetLegalKey(Key);
bytesIV = GetValidIV(IV);
// call our base constructor
__CryptoSymmetric(crypto, HashAlgorithm.None);
}
///
/// Initializes an instance of the CryptoSymmetric class.
///
public CryptoSymmetric(CryptoAlgorithm crypto, byte[] Key)
{
// initialize the encryption Key and use Key as IV
bytesKey = GetLegalKey(Key);
bytesIV = GetValidIV(Key);
// call our base constructor
__CryptoSymmetric(crypto, HashAlgorithm.None);
}
///
/// Initializes an instance of the CryptoSymmetric class.
///
public CryptoSymmetric(CryptoAlgorithm crypto, byte[] Key, byte[] IV)
{
// initialize the encryption Key, IV
bytesKey = GetLegalKey(Key);
bytesIV = GetValidIV(IV);
// call our base constructor
__CryptoSymmetric(crypto, HashAlgorithm.None);
}
///
/// Initializes an instance of the CryptoSymmetric class.
/// The designated HashAlgorithm will be used to hash the key for encryption/decryption.
///
public CryptoSymmetric(CryptoAlgorithm crypto, HashAlgorithm hash)
{
// call our base constructor
__CryptoSymmetric(crypto, hash);
}
///
/// Initializes an instance of the CryptoSymmetric class.
/// The designated HashAlgorithm will be used to hash the key for encryption/decryption.
///
public CryptoSymmetric(CryptoAlgorithm crypto, HashAlgorithm hash, string Key)
{
// initialize the encryption Key and use Key as IV
bytesKey = GetLegalKey(Key);
bytesIV = GetValidIV(Key);
// call our base constructor
__CryptoSymmetric(crypto, hash);
}
///
/// Initializes an instance of the CryptoSymmetric class.
/// The designated HashAlgorithm will be used to hash the key for encryption/decryption.
///
public CryptoSymmetric(CryptoAlgorithm crypto, HashAlgorithm hash, string Key, string IV)
{
// initialize the encryption Key, IV
bytesKey = GetLegalKey(Key);
bytesIV = GetValidIV(IV);
// call our base constructor
__CryptoSymmetric(crypto, hash);
}
///
/// Initializes an instance of the CryptoSymmetric class.
/// The designated HashAlgorithm will be used to hash the key for encryption/decryption.
///
public CryptoSymmetric(CryptoAlgorithm crypto, HashAlgorithm hash, byte[] Key)
{
// initialize the encryption Key and use Key as IV
bytesKey = GetLegalKey(Key);
bytesIV = GetValidIV(Key);
// call our base constructor
__CryptoSymmetric(crypto, hash);
}
///
/// Initializes an instance of the CryptoSymmetric class.
/// The designated HashAlgorithm will be used to hash the key for encryption/decryption.
///
public CryptoSymmetric(CryptoAlgorithm crypto, HashAlgorithm hash, byte[] Key, byte[] IV)
{
// initialize the encryption Key, IV
bytesKey = GetLegalKey(Key);
bytesIV = GetValidIV(IV);
// call our base constructor
__CryptoSymmetric(crypto, hash);
}
///
/// Base Constructor to be used to initialize a new instance of the CryptoSymmetric class.
///
private void __CryptoSymmetric(CryptoAlgorithm crypto, HashAlgorithm hash)
{
// set the crypto algorithm, obtain the proper cryptoserviceprovider
algorithmID = crypto;
switch (algorithmID)
{
case CryptoAlgorithm.DES:
{
objCryptoService = new DESCryptoServiceProvider();
break;
}
case CryptoAlgorithm.RC2:
{
objCryptoService = new RC2CryptoServiceProvider();
break;
}
case CryptoAlgorithm.Rijndael:
{
objCryptoService = new RijndaelManaged();
break;
}
case CryptoAlgorithm.TripleDES:
{
objCryptoService = new TripleDESCryptoServiceProvider();
break;
}
}
// now set the hash algorithm
hashID = hash;
}
#endregion
#region CreateServiceProvider
///
/// Returns the specified symmetric cryptographic service provider to enable
/// encryption/decryption to occur. Based on the supplied CryptoMethod,
/// this method will return the encryptor or decryptor.
/// Cipher-Block-Chaining mode is currently used for all algorithms.
///
private ICryptoTransform CreateServiceProvider(CryptoMethod method)
{
// if we get this far without having set a key, just throw the exception and leave
if (bytesKey == null)
{
throw new CryptographicException("A key is required to " + method + " this data.");
}
// Pick the provider.
switch (algorithmID)
{
case CryptoAlgorithm.DES:
{
objCryptoService = new DESCryptoServiceProvider();
objCryptoService.Mode = CipherMode.CBC;
break;
}
case CryptoAlgorithm.TripleDES:
{
objCryptoService = new TripleDESCryptoServiceProvider();
objCryptoService.Mode = CipherMode.CBC;
break;
}
case CryptoAlgorithm.RC2:
{
objCryptoService = new RC2CryptoServiceProvider();
objCryptoService.Mode = CipherMode.CBC;
break;
}
case CryptoAlgorithm.Rijndael:
{
objCryptoService = new RijndaelManaged();
objCryptoService.Mode = CipherMode.CBC;
break;
}
}
// now determine whether to send back the encryptor or decryptor
switch(method)
{
case CryptoMethod.Encrypt:
return objCryptoService.CreateEncryptor(bytesKey, bytesIV);
case CryptoMethod.Decrypt:
return objCryptoService.CreateDecryptor(bytesKey, bytesIV);
default:
{
throw new CryptographicException("Method '" + method + "' not supported.");
}
}
}
#endregion
#region Validation Methods for Key/IV
///
/// Wrapper method to allow a string to be passed in to determine
/// if Key is legal for the specified symmetric algorithm.
/// Returns the byte array of the legal key.
///
private byte[] GetLegalKey(string Key)
{
// return the Key
return GetLegalKey(ASCIIEncoding.ASCII.GetBytes(Key));
}
///
/// Takes a supplied byte array Key and determines if Key is legal for
/// the specified symmetric algorithm. If the hash algorithm has been designated,
/// the Key will be hashed before it is checked for validity.
/// Returns the byte array of the legal key.
///
private byte[] GetLegalKey(byte[] Key)
{
byte[] bTemp, bHash;
char cPadChar = ' ';
// first determine if we are to hash the key or not
switch(hashID)
{
case HashAlgorithm.MD5:
MD5CryptoServiceProvider hashMD5 = new MD5CryptoServiceProvider();
bHash = hashMD5.ComputeHash(Key);
// now use the hash as our key
Key = bHash;
break;
case HashAlgorithm.SHA1:
SHA1CryptoServiceProvider hashSHA1 = new SHA1CryptoServiceProvider();
bHash = hashSHA1.ComputeHash(Key);
// now use the hash as our key
Key = bHash;
break;
case HashAlgorithm.SHA256:
SHA256 hashSHA256 = new SHA256Managed();
bHash = hashSHA256.ComputeHash(Key);
// now use the hash as our key
Key = bHash;
break;
case HashAlgorithm.SHA384:
SHA384 hashSHA384 = new SHA384Managed();
bHash = hashSHA384.ComputeHash(Key);
// now use the hash as our key
Key = bHash;
break;
case HashAlgorithm.SHA512:
SHA512 hashSHA512 = new SHA512Managed();
bHash = hashSHA512.ComputeHash(Key);
// now use the hash as our key
Key = bHash;
break;
}
if (objCryptoService.LegalKeySizes.Length > 0)
{
int MinSize = objCryptoService.LegalKeySizes[0].MinSize;
int MaxSize = objCryptoService.LegalKeySizes[0].MaxSize;
// key sizes are in bits
// if the key size is too small, pad the right with spaces
if ((Key.Length * 8) < MinSize)
{
bTemp = new byte[MinSize / 8];
// first grab everything from the supplied key
Key.CopyTo(bTemp, 0);
// now add spaces to the key
for (int i = Key.Length; i < (MinSize / 8); i++)
bTemp[i] = Convert.ToByte(cPadChar);
} else
// if the key is too large, shorten it to fit
if ((Key.Length * 8) > MaxSize)
{
bTemp = new byte[MaxSize / 8];
// now grab everything up to the cutoff point
for (int j = 0; j < bTemp.Length; j++)
bTemp[j] = Key[j];
} else {
int iByteCount = Key.Length;
while(!objCryptoService.ValidKeySize(iByteCount * 8))
iByteCount++;
// now create a new byte array of size iByteCount
bTemp = new byte[iByteCount];
// grab everything we can from the supplied key
Key.CopyTo(bTemp, 0);
// now add spaces to the key
for (int k = Key.Length; k < bTemp.Length; k++)
bTemp[k] = Convert.ToByte(cPadChar);
}
} else {
throw new CryptographicException("A Symmetric Algorithm must be selected in order to perform this operation.");
}
// return the byte array
return bTemp;
}
///
/// Wrapper method to allow a string to be passed in to determine
/// if IV is valid for the specified symmetric algorithm.
/// Returns the byte array of the valid IV.
///
private byte[] GetValidIV(string IV)
{
// return the byte array
return GetValidIV(ASCIIEncoding.ASCII.GetBytes(IV));
}
///
/// Takes a supplied byte array IV and determines if IV is valid for
/// the specified symmetric algorithm.
/// Returns the byte array of the valid IV.
///
private byte[] GetValidIV(byte[] IV)
{
byte[] bTemp = new byte[1];
char cPadChar = ' ';
int i;
switch(algorithmID)
{
case CryptoAlgorithm.DES:
case CryptoAlgorithm.RC2:
case CryptoAlgorithm.TripleDES:
// use 64 bit IV for DES, RC2 and TripleDES
bTemp = new byte[8];
break;
case CryptoAlgorithm.Rijndael:
// use 128 bit IV for Rijndael
bTemp = new byte[16];
break;
}
// if IV has more bytes than we need, just grab as many as we can fit in bTemp
// otherwise, grab them all, and pad out the remaining spots with spaces
if (IV.Length >= bTemp.Length)
{
for (i = 0; i < bTemp.Length; i++)
bTemp[i] = IV[i];
} else {
// grab what we have
IV.CopyTo(bTemp, 0);
// now fill the rest with spaces
for (i = IV.Length; i < bTemp.Length; i++)
bTemp[i] = Convert.ToByte(cPadChar);
}
// return byte array
return bTemp;
}
#endregion
#region String Encryption/Decryption
#region String Encryption Methods
///
/// Encrypts the supplied string and returns the ciphertext.
/// The CryptoSymmetric object must have its key and initialization vector defined.
///
public string EncryptString(string Source)
{
return __EncryptString(Source);
}
///
/// Encrypts the supplied string and returns the ciphertext.
/// The CryptoSymmetric object will encrypt using the supplied Key for the key and initialization vector.
///
public string EncryptString(string Source, byte[] Key)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV using the supplied Key
bytesIV = GetValidIV(Key);
return __EncryptString(Source);
}
///
/// Encrypts the supplied string and returns the ciphertext.
/// The CryptoSymmetric object will encrypt using the supplied Key and IV.
///
public string EncryptString(string Source, byte[] Key, byte[] IV)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV
bytesIV = GetValidIV(IV);
return __EncryptString(Source);
}
///
/// Encrypts the supplied string and returns the ciphertext.
/// The CryptoSymmetric object will encrypt using the supplied Key for the key and initialization vector.
///
public string EncryptString(string Source, string Key)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV using the supplied Key
bytesIV = GetValidIV(Key);
return __EncryptString(Source);
}
///
/// Encrypts the supplied string and returns the ciphertext.
/// The CryptoSymmetric object will encrypt using the supplied Key and IV.
///
public string EncryptString(string Source, string Key, string IV)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV
bytesIV = GetValidIV(IV);
return __EncryptString(Source);
}
///
/// The main EncryptString function. The function creates a MemoryStream, a CryptoStream
/// and obtains an ICryptoTransform interface. The CryptoStream then
/// uses the supplied source string and writes out the encrypted
/// text to the MemoryStream using the ICryptoTransform interface.
///
private string __EncryptString(string Source)
{
byte[] bInput = System.Text.ASCIIEncoding.ASCII.GetBytes(Source);
// create a MemoryStream so that the process can be done without I/O files
MemoryStream ms = new MemoryStream();
// create an Encryptor
ICryptoTransform encrypto = CreateServiceProvider(CryptoMethod.Encrypt);
// create Crypto Stream that transforms a stream using the encryption
CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
// write out encrypted content into MemoryStream
cs.Write(bInput, 0, bInput.Length);
cs.FlushFinalBlock();
// get the output
byte[] bOutput = ms.ToArray();
// close our streams
cs.Close();
ms.Close();
// convert into Base64 so that the result can be used in xml
return Convert.ToBase64String(bOutput, 0, bOutput.Length);
}
#endregion
#region String Decryption Methods
///
/// Decrypts the supplied string and returns the plaintext.
/// The CryptoSymmetric object must have its key and initialization vector defined.
///
public string DecryptString(string Source)
{
return __DecryptString(Source);
}
///
/// Decrypts the supplied string and returns the plaintext.
/// The CryptoSymmetric object will decrypt using the supplied Key for the key and initialization vector.
///
public string DecryptString(string Source, byte[] Key)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV using the supplied Key
bytesIV = GetValidIV(Key);
return __DecryptString(Source);
}
///
/// Decrypts the supplied string and returns the plaintext.
/// The CryptoSymmetric object will decrypt using the supplied Key and IV.
///
public string DecryptString(string Source, byte[] Key, byte[] IV)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV
bytesIV = GetValidIV(IV);
return __DecryptString(Source);
}
///
/// Decrypts the supplied string and returns the plaintext.
/// The CryptoSymmetric object will decrypt using the supplied Key for the key and initialization vector.
///
public string DecryptString(string Source, string Key)
{
// set the supplied key as the decryption key
bytesKey = GetLegalKey(Key);
// set the IV using the supplied Key
bytesIV = GetValidIV(Key);
return __DecryptString(Source);
}
///
/// Decrypts the supplied string and returns the plaintext.
/// The CryptoSymmetric object will decrypt using the supplied Key and IV.
///
public string DecryptString(string Source, string Key, string IV)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV
bytesIV = GetValidIV(IV);
return __DecryptString(Source);
}
///
/// The main DecryptString function. The function creates a MemoryStream, a CryptoStream
/// and obtains an ICryptoTransform interface. The CryptoStream then
/// uses the supplied source string and writes out the decrypted
/// text to the MemoryStream using the ICryptoTransform interface.
///
private string __DecryptString(string Source)
{
// convert from Base64 to binary
byte[] bInput = System.Convert.FromBase64String(Source);
// create a MemoryStream with the input
MemoryStream ms = new MemoryStream(bInput, 0, bInput.Length);
// create a Decryptor
ICryptoTransform decrypto = CreateServiceProvider(CryptoMethod.Decrypt);
// create Crypto Stream that transforms the stream using the decryption
CryptoStream cs = new CryptoStream(ms, decrypto, CryptoStreamMode.Read);
// allocate the buffer long enough to hold ciphertext (plaintext is never longer than ciphertext)
byte[] bOutput = new byte[bInput.Length];
// Start decrypting.
int decryptedByteCount = cs.Read(bOutput, 0, bOutput.Length);
// Close both streams.
cs.Close();
ms.Close();
// Convert decrypted data into a string.
return Encoding.ASCII.GetString(bOutput, 0, decryptedByteCount);
}
#endregion
#endregion
#region File Encryption/Decryption
#region File Encryption Methods
///
/// Encrypts the file at the path ReadFile and outputs the encrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object must have its key and initialization vector defined.
/// Returns true on success and false on failure.
///
public bool EncryptFile(string ReadFile, string WriteFile)
{
return __EncryptFile(ReadFile, WriteFile);
}
///
/// Encrypts the file at the path ReadFile and outputs the encrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object will encrypt using the supplied Key for the key and initialization vector.
/// Returns true on success and false on failure.
///
public bool EncryptFile(string ReadFile, string WriteFile, byte[] Key)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV using the supplied Key
bytesIV = GetValidIV(Key);
return __EncryptFile(ReadFile, WriteFile);
}
///
/// Encrypts the file at the path ReadFile and outputs the encrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object will encrypt using the supplied Key and IV.
/// Returns true on success and false on failure.
///
public bool EncryptFile(string ReadFile, string WriteFile, byte[] Key, byte[] IV)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV
bytesIV = GetValidIV(IV);
return __EncryptFile(ReadFile, WriteFile);
}
///
/// Encrypts the file at the path ReadFile and outputs the encrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object will encrypt using the supplied Key for the key and initialization vector.
/// Returns true on success and false on failure.
///
public bool EncryptFile(string ReadFile, string WriteFile, string Key)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV using the supplied Key
bytesIV = GetValidIV(Key);
return __EncryptFile(ReadFile, WriteFile);
}
///
/// Encrypts the file at the path ReadFile and outputs the encrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object will encrypt using the supplied Key and IV.
/// Returns true on success and false on failure.
///
public bool EncryptFile(string ReadFile, string WriteFile, string Key, string IV)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV
bytesIV = GetValidIV(IV);
return __EncryptFile(ReadFile, WriteFile);
}
///
/// The main EncryptFile function. The function creates a FileStream, a CryptoStream
/// and obtains an ICryptoTransform interface. The CryptoStream then
/// uses the file at the target path ReadFile and writes out the encrypted
/// file to the FileStream using the ICryptoTransform interface.
///
private bool __EncryptFile(string ReadFile, string WriteFile)
{
// assume false at start
bool bSuccess = false;
// verify the file we're supposed to read in actually exists!
if (!File.Exists(ReadFile))
throw new Exception("File to encrypt does not exist!");
// create new FileStreams for input, output
FileStream fsIn = new FileStream(ReadFile, FileMode.Open, FileAccess.Read);
FileStream fsOut = new FileStream(WriteFile, FileMode.OpenOrCreate, FileAccess.Write);
fsOut.SetLength(0);
// create an Encryptor
ICryptoTransform encrypto = CreateServiceProvider(CryptoMethod.Encrypt);
// create Crypto Stream that transforms a stream using the encryption
CryptoStream cs = new CryptoStream(fsOut, encrypto, CryptoStreamMode.Write);
try
{
byte[] bInput = new byte[fsIn.Length];
fsIn.Read(bInput, 0, bInput.Length);
cs.Write(bInput, 0, bInput.Length);
// we made it!
bSuccess = true;
}
finally
{
// close our streams
cs.Close();
fsOut.Close();
fsIn.Close();
}
// return success or not
return bSuccess;
}
#endregion
#region File Decryption Methods
///
/// Decrypts the file at the path ReadFile and outputs the decrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object must have its key and initialization vector defined.
/// Returns true on success and false on failure.
///
public bool DecryptFile(string ReadFile, string WriteFile)
{
return __DecryptFile(ReadFile, WriteFile);
}
///
/// Decrypts the file at the path ReadFile and outputs the decrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object will decrypt using the supplied Key for the key and initialization vector.
/// Returns true on success and false on failure.
///
public bool DecryptFile(string ReadFile, string WriteFile, byte[] Key)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV using the supplied Key
bytesIV = GetValidIV(Key);
return __DecryptFile(ReadFile, WriteFile);
}
///
/// Decrypts the file at the path ReadFile and outputs the decrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object will decrypt using the supplied Key and IV.
/// Returns true on success and false on failure.
///
public bool DecryptFile(string ReadFile, string WriteFile, byte[] Key, byte[] IV)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV
bytesIV = GetValidIV(IV);
return __DecryptFile(ReadFile, WriteFile);
}
///
/// Decrypts the file at the path ReadFile and outputs the decrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object will decrypt using the supplied Key for the key and initialization vector.
/// Returns true on success and false on failure.
///
public bool DecryptFile(string ReadFile, string WriteFile, string Key)
{
// set the supplied key as the decryption key
bytesKey = GetLegalKey(Key);
// set the IV using the supplied Key
bytesIV = GetValidIV(Key);
return __DecryptFile(ReadFile, WriteFile);
}
///
/// Decrypts the file at the path ReadFile and outputs the decrypted
/// file to the path WriteFile.
/// The CryptoSymmetric object will decrypt using the supplied Key and IV.
/// Returns true on success and false on failure.
///
public bool DecryptFile(string ReadFile, string WriteFile, string Key, string IV)
{
// set the supplied key as the encryption key
bytesKey = GetLegalKey(Key);
// set the IV
bytesIV = GetValidIV(IV);
return __DecryptFile(ReadFile, WriteFile);
}
///
/// The main DecryptFile function. The function creates a FileStream, a CryptoStream
/// and obtains an ICryptoTransform interface. The CryptoStream then
/// uses the file at the target path ReadFile and writes out the decrypted
/// file to the FileStream using the ICryptoTransform interface.
///
private bool __DecryptFile(string ReadFile, string WriteFile)
{
// assume false at start
bool bSuccess = false;
// verify the file we're supposed to read in actually exists!
if (!File.Exists(ReadFile))
throw new Exception("File to decrypt does not exist!");
// create new FileStreams for input, output
FileStream fsIn = new FileStream(ReadFile, FileMode.Open, FileAccess.Read);
FileStream fsOut = new FileStream(WriteFile, FileMode.Create, FileAccess.Write);
fsOut.SetLength(0);
// create a Decryptor
ICryptoTransform decrypto = CreateServiceProvider(CryptoMethod.Decrypt);
// create Crypto Stream that transforms the stream using the decryption
CryptoStream cs = new CryptoStream(fsOut, decrypto, CryptoStreamMode.Write);
try
{
// write out decrypted content into FileStream
byte[] bInput = new byte[fsIn.Length];
fsIn.Read(bInput, 0, bInput.Length);
cs.Write(bInput, 0, bInput.Length);
// we made it!
bSuccess = true;
}
finally
{
// Close both streams.
cs.Close();
fsOut.Close();
fsIn.Close();
}
// return success or not
return bSuccess;
}
#endregion
#endregion
}
}