using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
namespace Demo
{
public enum CryptoAlgo
{
DES,
RC2,
Rijndael,
TripleDES
}
public class Crypto : IDisposable
{
// Call this function to remove the key from memory after use for security
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint= "RtlZeroMemory")]
private static extern bool ZeroMemory(IntPtr Destination, int Length);
private SymmetricAlgorithm cAlgo;
private readonly int BufSize = 1024;
public Crypto(CryptoAlgo algo) : this(algo, null, null)
{
}
public Crypto(CryptoAlgo algo, string key, string iv)
{
switch (algo)
{
case CryptoAlgo.DES:
cAlgo = DES.Create();
break;
case CryptoAlgo.RC2:
cAlgo = RC2.Create();
break;
case CryptoAlgo.Rijndael:
cAlgo = Rijndael.Create();
break;
case CryptoAlgo.TripleDES:
cAlgo = TripleDES.Create();
break;
default:
throw new ArgumentOutOfRangeException("algo");
}
if (key != null)
{
cAlgo.Key = Convert.FromBase64String(key);
cAlgo.IV = Convert.FromBase64String(iv);
}
}
///
/// Gets the key for the algorithm as a Base64 string.
///
public string Key
{
get
{
return Convert.ToBase64String(cAlgo.Key);
}
}
///
/// Gets the IV for the algorithm as a Base64 string.
///
public string IV
{
get { return Convert.ToBase64String(cAlgo.IV); }
}
public void EncryptFile(string inPath, string outPath)
{
using (FileStream inStream = File.OpenRead(inPath))
using (FileStream outStream = new FileStream(outPath, FileMode.Create, FileAccess.Write))
{
EncryptStream(inStream, outStream);
}
}
public void DecryptFile(string inPath, string outPath)
{
using (FileStream inStream = File.OpenRead(inPath))
using (FileStream outStream = new FileStream(outPath, FileMode.Create, FileAccess.Write))
{
DecryptStream(inStream, outStream);
}
}
public byte[] EncryptBytes(byte[] buffer)
{
using (MemoryStream inStream = new MemoryStream(buffer))
using (MemoryStream outStream = new MemoryStream())
{
EncryptStream(inStream, outStream);
return outStream.ToArray();
}
}
public byte[] DecryptBytes(byte[] buffer)
{
using (MemoryStream inStream = new MemoryStream(buffer))
using (MemoryStream outStream = new MemoryStream())
{
DecryptStream(inStream, outStream);
return outStream.ToArray();
}
}
public void EncryptStream(Stream inStream, Stream outStream)
{
using (ICryptoTransform encryptor = cAlgo.CreateEncryptor())
using (CryptoStream cryptoStream = new CryptoStream(outStream, encryptor, CryptoStreamMode.Write))
{
// Read from in file until EOF and write to crypto stream.
byte[] buf = new byte[BufSize];
int read = 0;
while ((read = inStream.Read(buf, 0, buf.Length)) > 0)
{
cryptoStream.Write(buf, 0, read);
}
cryptoStream.Flush();
outStream.Flush();
}
}
public void DecryptStream(Stream inStream, Stream outStream)
{
using (ICryptoTransform decryptor = cAlgo.CreateDecryptor())
using (CryptoStream cryptoStream = new CryptoStream(inStream, decryptor, CryptoStreamMode.Read))
{
// Read from the cryptoStream until EOF and write decrypted bytes to outFile.
byte[] ba = new byte[BufSize];
int read = 0;
while ((read = cryptoStream.Read(ba, 0, ba.Length)) > 0)
{
outStream.Write(ba, 0, read);
}
outStream.Flush();
}
}
public static void Test()
{
Crypto crypto = new Crypto(CryptoAlgo.DES);
string key = crypto.Key;
string iv = crypto.IV;
crypto.EncryptFile("c:\\mydata.txt", "c:\\encrypted.txt");
crypto.DecryptFile("c:\\encrypted.txt", "c:\\decrypted.txt");
Console.WriteLine("Decrypted.txt:");
Console.WriteLine(File.ReadAllText("c:\\decrypted.txt")); // Will work for text files.
// Test decrypting with stored key.
crypto = new Crypto(CryptoAlgo.DES, key, iv);
crypto.DecryptFile("c:\\encrypted.txt", "c:\\decrypted.txt");
Console.WriteLine("Decrypted.txt:");
Console.WriteLine(File.ReadAllText("c:\\decrypted.txt")); // Will work for text files.
}
public void Dispose()
{
this.cAlgo.Clear();
}
}
No comments:
Post a Comment