// (c) 2006 Richard Grimes
// www.grimes.demon.co.uk
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
class App
{
static void Main(string[] args)
{
if (args.Length < 3)
{
Console.WriteLine("command line: [e|d]");
Console.WriteLine("\twhere e means encrypt (the default) and d means decrypt");
return;
}
bool bEncrypt = true;
if (args.Length == 4) bEncrypt = (args[3].ToLower()[0] == 'e');
FileStream fsIn = new FileStream(args[0], FileMode.Open);
FileStream fsOut = new FileStream(args[1], FileMode.Create);
if (bEncrypt) Encrypt(fsIn, fsOut, args[2]);
else Decrypt(fsIn, fsOut, args[2]);
}
static void Encrypt(Stream sIn, Stream sOut, string password)
{
Rijndael r = Rijndael.Create();
byte[] salt = null;
byte[] pass = null;
CreatePassword(password, r.KeySize >> 3, r.KeySize >> 3, out pass, ref salt);
r.Key = pass;
sOut.Write(salt, 0, salt.Length);
sOut.Write(r.IV, 0, r.IV.Length);
CryptoStream cs = new CryptoStream(sIn, r.CreateEncryptor(), CryptoStreamMode.Read);
byte[] buffer = new byte[1024];
while (true)
{
int read = cs.Read(buffer, 0, buffer.Length);
if (read == 0) break;
sOut.Write(buffer, 0, read);
}
cs.Close(); // closes sIn
sOut.Close();
}
static void Decrypt(Stream sIn, Stream sOut, string password)
{
Rijndael r = Rijndael.Create();
byte[] salt = new byte[r.KeySize >> 3];
byte[] pass = null;
sIn.Read(salt, 0, salt.Length);
CreatePassword(password, r.KeySize >> 3, r.KeySize >> 3, out pass, ref salt);
r.Key = pass;
byte[] IV = new byte[r.IV.Length];
sIn.Read(IV, 0, IV.Length);
r.IV = IV;
CryptoStream cs = new CryptoStream(sOut, r.CreateDecryptor(), CryptoStreamMode.Write);
byte[] buffer = new byte[1024];
while (true)
{
int read = sIn.Read(buffer, 0, buffer.Length);
if (read == 0) break;
cs.Write(buffer, 0, read);
}
cs.FlushFinalBlock();
sIn.Close();
cs.Close(); // closes sOut
}
static void CreatePassword(string phrase, int saltSize, int passSize, out byte[] pass, ref byte[] salt)
{
if (salt == null)
{
RandomNumberGenerator rand = RandomNumberGenerator.Create();
salt = new byte[saltSize];
rand.GetBytes(salt);
}
PasswordDeriveBytes pdb = new PasswordDeriveBytes(phrase, salt);
pass = pdb.GetBytes(passSize);
}
}