Ok, last one. Made more general to handle all currently supported symmetric
algos. Also changed to use Streams instead of just files, so can do with
any stream and added helpers over the stream overloads to work with files
and buffers. Also makes IV required.
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("KER NEL32.DLL", EntryPoint
= "RtlZeroMemory" )]
private static extern bool ZeroMemory(IntP tr Destination, int
Length);
private SymmetricAlgori thm cAlgo;
private readonly int BufSize = 1024;
public Crypto(CryptoAl go algo) : this(algo, null, null)
{
}
public Crypto(CryptoAl go algo, string key, string iv)
{
switch (algo)
{
case CryptoAlgo.DES:
cAlgo = DES.Create();
break;
case CryptoAlgo.RC2:
cAlgo = RC2.Create();
break;
case CryptoAlgo.Rijn dael:
cAlgo = Rijndael.Create ();
break;
case CryptoAlgo.Trip leDES:
cAlgo = TripleDES.Creat e();
break;
default:
throw new ArgumentOutOfRa ngeException("a lgo");
}
if (key != null)
{
cAlgo.Key = Convert.FromBas e64String(key);
cAlgo.IV = Convert.FromBas e64String(iv);
}
}
/// <summary>
/// Gets the key for the algorithm as a Base64 string.
/// </summary>
public string Key
{
get
{
return Convert.ToBase6 4String(cAlgo.K ey);
}
}
/// <summary>
/// Gets the IV for the algorithm as a Base64 string.
/// </summary>
public string IV
{
get { return Convert.ToBase6 4String(cAlgo.I V); }
}
public void EncryptFile(str ing inPath, string outPath)
{
using (FileStream inStream = File.OpenRead(i nPath))
using (FileStream outStream = new FileStream(outP ath,
FileMode.Create , FileAccess.Writ e))
{
EncryptStream(i nStream, outStream);
}
}
public void DecryptFile(str ing inPath, string outPath)
{
using (FileStream inStream = File.OpenRead(i nPath))
using (FileStream outStream = new FileStream(outP ath,
FileMode.Create , FileAccess.Writ e))
{
DecryptStream(i nStream, outStream);
}
}
public byte[] EncryptBytes(by te[] buffer)
{
using (MemoryStream inStream = new MemoryStream(bu ffer))
using (MemoryStream outStream = new MemoryStream())
{
EncryptStream(i nStream, outStream);
return outStream.ToArr ay();
}
}
public byte[] DecryptBytes(by te[] buffer)
{
using (MemoryStream inStream = new MemoryStream(bu ffer))
using (MemoryStream outStream = new MemoryStream())
{
DecryptStream(i nStream, outStream);
return outStream.ToArr ay();
}
}
public void EncryptStream(S tream inStream, Stream outStream)
{
using (ICryptoTransfo rm encryptor = cAlgo.CreateEnc ryptor())
using (CryptoStream cryptoStream = new CryptoStream(ou tStream,
encryptor, CryptoStreamMod e.Write))
{
// Read from in file until EOF and write to crypto stream.
byte[] buf = new byte[BufSize];
int read = 0;
while ((read = inStream.Read(b uf, 0, buf.Length)) 0)
{
cryptoStream.Wr ite(buf, 0, read);
}
cryptoStream.Fl ush();
outStream.Flush ();
}
}
public void DecryptStream(S tream inStream, Stream outStream)
{
using (ICryptoTransfo rm decryptor = cAlgo.CreateDec ryptor())
using (CryptoStream cryptoStream = new CryptoStream(in Stream,
decryptor, CryptoStreamMod e.Read))
{
// Read from the cryptoStream until EOF and write decrypted
bytes to outFile.
byte[] ba = new byte[BufSize];
int read = 0;
while ((read = cryptoStream.Re ad(ba, 0, ba.Length)) 0)
{
outStream.Write (ba, 0, read);
}
outStream.Flush ();
}
}
public static void Test()
{
Crypto crypto = new Crypto(CryptoAl go.DES);
string key = crypto.Key;
string iv = crypto.IV;
crypto.EncryptF ile("c:\\mydata .txt", "c:\\encrypted. txt");
crypto.DecryptF ile("c:\\encryp ted.txt", "c:\\decrypted. txt");
Console.WriteLi ne("Decrypted.t xt:");
Console.WriteLi ne(File.ReadAll Text("c:\\decry pted.txt")); //
Will work for text files.
// Test decrypting with stored key.
crypto = new Crypto(CryptoAl go.DES, key, iv);
crypto.DecryptF ile("c:\\encryp ted.txt", "c:\\decrypted. txt");
Console.WriteLi ne("Decrypted.t xt:");
Console.WriteLi ne(File.ReadAll Text("c:\\decry pted.txt")); //
Will work for text files.
}
public void Dispose()
{
this.cAlgo.Clea r();
}
}
}
--
William Stacey [C# MVP]
PCR concurrency library:
www.codeplex.com/pcr
PSH Scripts Project
www.codeplex.com/psobject
"William Stacey [C# MVP]" <wi************ @gmail.comwrote in message
news:%2******** ********@TK2MSF TNGP04.phx.gbl. ..
| Actually, here is a better one that handles any size file in buffer size
| chunks.
|
| using System;
| using System.IO;
| using System.Security ;
| using System.Security .Cryptography;
| using System.Runtime. InteropServices ;
| using System.Text;
|
| namespace Demo
| {
| public class Class1
| {
| // Call this function to remove the key from memory after use for
| security
| [System.Runtime. InteropServices .DllImport("KER NEL32.DLL",
EntryPoint
| = "RtlZeroMemory" )]
| public static extern bool ZeroMemory(IntP tr Destination, int
| Length);
|
| const int BufSize = 1024;
|
| // Function to Generate a 64 bits Key.
| public static string GenerateKey()
| {
| // Create an instance of Symetric Algorithm. Key and IV is
| generated automatically.
| DES des = DES.Create();
| return Encoding.ASCII. GetString(des.K ey);
| }
|
| public static void EncryptFile(str ing inPath, string outPath,
string
| sKey)
| {
| DES des = DES.Create();
|
| using (FileStream inFile = File.OpenRead(i nPath))
| using (FileStream outFile = new FileStream(outP ath,
| FileMode.Create , FileAccess.Writ e))
| using (ICryptoTransfo rm desencrypt =
| des.CreateEncry ptor(Encoding.A SCII.GetBytes(s Key),
| Encoding.ASCII. GetBytes(sKey)) )
| using (CryptoStream cryptoStream = new CryptoStream(ou tFile,
| desencrypt, CryptoStreamMod e.Write))
| {
| // Read from in file until EOF and write to crypto stream.
| byte[] buf = new byte[BufSize];
| int read = 0;
| while ((read = inFile.Read(buf , 0, buf.Length)) 0)
| {
| cryptoStream.Wr ite(buf, 0, read);
| }
| cryptoStream.Fl ush();
| outFile.Flush() ;
| }
| }
|
| public static void DecryptFile(str ing inPath, string outPath,
string
| sKey)
| {
| //A 64 bit key and IV is required for this provider.
| //Set secret key For DES algorithm.
| DES des = DES.Create();
|
| using (FileStream inFile = new FileStream(inPa th,
FileMode.Open,
| FileAccess.Read ))
| using (FileStream outFile = File.OpenWrite( outPath))
| using (ICryptoTransfo rm desdecrypt =
| des.CreateDecry ptor(Encoding.A SCII.GetBytes(s Key),
| Encoding.ASCII. GetBytes(sKey)) )
| using (CryptoStream cryptoStream = new CryptoStream(in File,
| desdecrypt, CryptoStreamMod e.Read))
| {
| // Read from the cryptoStream until EOF and write decrypted
| bytes to outFile.
| byte[] ba = new byte[BufSize];
| int read = 0;
| while ((read = cryptoStream.Re ad(ba, 0, ba.Length)) 0)
| {
| outFile.Write(b a, 0, read);
| }
| outFile.Flush() ;
| }
| }
|
| public static void DoCrypto()
| {
| // Must be 64 bits, 8 bytes.
| // Distribute this key to the user who will decrypt this file.
| string sSecretKey;
|
| // Get the Key for the file to Encrypt.
| sSecretKey = GenerateKey();
|
| // For additional security Pin the key.
| GCHandle gch = GCHandle.Alloc( sSecretKey, GCHandleType.Pi nned);
|
| // Encrypt the file.
| EncryptFile(@"C :\MyData.txt", @"C:\Encrypted. txt", sSecretKey);
| Console.WriteLi ne("Encrypted") ;
|
| // Decrypt the file.
| DecryptFile(@"C :\Encrypted.txt ",
| @"C:\Decrypted. txt",sSecretKey );
| Console.WriteLi ne("Decrypted." );
|
| // Remove the Key from memory.
| ZeroMemory(gch. AddrOfPinnedObj ect(), sSecretKey.Leng th * 2);
| gch.Free();
|
| Console.WriteLi ne("Done.");
| Console.WriteLi ne("Cat Decrypted.txt:" );
| Cat(@"c:\decryp ted.txt");
| }
|
| public static void Cat(string path)
| {
| Console.WriteLi ne(File.ReadAll Text(path));
| }
| }
| }
|
| --
| William Stacey [C# MVP]
| PCR concurrency library:
www.codeplex.com/pcr
| PSH Scripts Project
www.codeplex.com/psobject
|
|
| "William Stacey [C# MVP]" <wi************ @gmail.comwrote in message
| news:O3******** ******@TK2MSFTN GP06.phx.gbl...
|| Works over here. Well with text files. It is not a good sample. Try
|| something more like:
||
|| using System;
|| using System.IO;
|| using System.Security ;
|| using System.Security .Cryptography;
|| using System.Runtime. InteropServices ;
|| using System.Text;
||
|| namespace Demo
|| {
|| public class Class1
|| {
|| // Call this function to remove the key from memory after use for
|| security
|| [System.Runtime. InteropServices .DllImport("KER NEL32.DLL",
| EntryPoint
|| = "RtlZeroMemory" )]
|| public static extern bool ZeroMemory(IntP tr Destination, int
|| Length);
||
|| // Function to Generate a 64 bits Key.
|| public static string GenerateKey()
|| {
|| // Create an instance of Symetric Algorithm. Key and IV is
|| generated automatically.
|| DESCryptoServic eProvider desCrypto =
|| (DESCryptoServi ceProvider)DESC ryptoServicePro vider.Create();
||
|| // Use the Automatically generated key for Encryption.
|| return ASCIIEncoding.A SCII.GetString( desCrypto.Key);
|| }
||
|| public static void EncryptFile(str ing sInputFilename, string
|| sOutputFilename , string sKey)
|| {
|| DESCryptoServic eProvider DES = new DESCryptoServic eProvider();
||
|| using (FileStream inFile = new FileStream(sInp utFilename,
|| FileMode.Open, FileAccess.Read ) )
|| using (FileStream outFile = new FileStream(sOut putFilename,
|| FileMode.Create , FileAccess.Writ e))
|| using (ICryptoTransfo rm desencrypt =
|| DES.CreateEncry ptor(Encoding.A SCII.GetBytes(s Key),
|| Encoding.ASCII. GetBytes(sKey)) )
|| using (CryptoStream cryptoStream = new CryptoStream(ou tFile,
|| desencrypt, CryptoStreamMod e.Write))
|| {
|| byte[] bytearrayinput = new byte[inFile.Length];
|| inFile.Read(byt earrayinput, 0, bytearrayinput. Length);
|| cryptoStream.Wr ite(bytearrayin put, 0,
|| bytearrayinput. Length);
|| cryptoStream.Fl ush();
|| outFile.Flush() ;
|| }
|| }
||
|| public static void DecryptFile(str ing sInputFilename, string
|| sOutputFilename , string sKey)
|| {
|| //A 64 bit key and IV is required for this provider.
|| //Set secret key For DES algorithm.
|| DESCryptoServic eProvider DES = new DESCryptoServic eProvider();
||
|| using (FileStream inFile = new FileStream(sInp utFilename,
|| FileMode.Open, FileAccess.Read ))
|| using (FileStream outFile = File.OpenWrite( sOutputFilename ))
|| using (ICryptoTransfo rm desdecrypt =
|| DES.CreateDecry ptor(Encoding.A SCII.GetBytes(s Key),
|| Encoding.ASCII. GetBytes(sKey)) )
|| using (CryptoStream cryptoStream = new CryptoStream(in File,
|| desdecrypt, CryptoStreamMod e.Read))
|| {
|| // Read from the cryptoStream until EOF and write
decrypted
|| bytes to outFile.
|| byte[] ba = new byte[1024];
|| int count = 0;
|| while ((count = cryptoStream.Re ad(ba, 0, ba.Length)) 0)
|| {
|| outFile.Write(b a, 0, count);
|| }
|| outFile.Flush() ;
|| }
|| }
||
|| public static void DoCrypto()
|| {
|| // Must be 64 bits, 8 bytes.
|| // Distribute this key to the user who will decrypt this file.
|| string sSecretKey;
||
|| // Get the Key for the file to Encrypt.
|| sSecretKey = GenerateKey();
||
|| // For additional security Pin the key.
|| GCHandle gch = GCHandle.Alloc( sSecretKey,
GCHandleType.Pi nned);
||
|| // Encrypt the file.
|| EncryptFile(@"C :\MyData.txt", @"C:\Encrypted. txt",
sSecretKey);
|| Console.WriteLi ne("Encrypted") ;
||
|| // Decrypt the file.
|| DecryptFile(@"C :\Encrypted.txt ",
|| @"C:\Decrypted. txt",sSecretKey );
|| Console.WriteLi ne("Decrypted." );
||
|| // Remove the Key from memory.
|| ZeroMemory(gch. AddrOfPinnedObj ect(), sSecretKey.Leng th * 2);
|| gch.Free();
||
|| Console.WriteLi ne("Done.");
|| Console.WriteLi ne("Cat Decrypted.txt:" );
|| Cat(@"c:\decryp ted.txt");
|| }
||
|| public static void Cat(string path)
|| {
|| Console.WriteLi ne(File.ReadAll Text(path));
|| }
|| }
|| }
||
||
|| --
|| William Stacey [C# MVP]
|| PCR concurrency library:
www.codeplex.com/pcr
|| PSH Scripts Project
www.codeplex.com/psobject
||
||
|| "JDeats" <Je**********@g mail.comwrote in message
|| news:11******** **************@ n76g2000hsh.goo glegroups.com.. .
|||I have some .NET 1.1 code that utilizes this technique for encrypting
||| and decrypting a file.
|||
http://support.microsoft.com/kb/307010
|||
||| In .NET 2.0 this approach is not fully supported (a .NET 2.0 build
||| with these methods, will appear to encrypt and decrypt, but the
||| resulting decrypted file will be corrupted. I tried encrypting a .bmp
||| file and then decrypting, the resulting decrypted file under .NET 2.0
||| is garbage, the .NET 1.1 build works as expected).
|||
||| I would like to know why this approach is no longer supported, aside
||| from building a .NET 1.1 class library and referencing it in my .NET
||| 2.0 project, what is the proper way to encrypt and decrypt a file
||| using ,NET 2.0 and the DES encryption algorithm.
|||
||
||
|
|