file.encrypt c# code example

Example 1: how to encrypt a file c#

//  Call this function to remove the key from memory after use for security
[DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
public static extern bool ZeroMemory(IntPtr Destination, int Length);

/// <summary>
/// Creates a random salt that will be used to encrypt your file. This method is required on FileEncrypt.
/// </summary>
/// <returns></returns>
public static byte[] GenerateRandomSalt()
{
    byte[] data = new byte[32];

    using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
    {
        for (int i = 0; i < 10; i++)
        {
            // Fille the buffer with the generated data
            rng.GetBytes(data);
        }
    }

    return data;
}

/// <summary>
/// Encrypts a file from its path and a plain password.
/// </summary>
/// <param name="inputFile"></param>
/// <param name="password"></param>
private void FileEncrypt(string inputFile, string password)
{
    //http://stackoverflow.com/questions/27645527/aes-encryption-on-large-files

    //generate random salt
    byte[] salt = GenerateRandomSalt();

    //create output file name
    FileStream fsCrypt = new FileStream(inputFile + ".aes", FileMode.Create);

    //convert password string to byte arrray
    byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password);

    //Set Rijndael symmetric encryption algorithm
    RijndaelManaged AES = new RijndaelManaged();
    AES.KeySize = 256;
    AES.BlockSize = 128;
    AES.Padding = PaddingMode.PKCS7;

    //http://stackoverflow.com/questions/2659214/why-do-i-need-to-use-the-rfc2898derivebytes-class-in-net-instead-of-directly
    //"What it does is repeatedly hash the user password along with the salt." High iteration counts.
    var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
    AES.Key = key.GetBytes(AES.KeySize / 8);
    AES.IV = key.GetBytes(AES.BlockSize / 8);

    //Cipher modes: http://security.stackexchange.com/questions/52665/which-is-the-best-cipher-mode-and-padding-mode-for-aes-encryption
    AES.Mode = CipherMode.CFB;

    // write salt to the begining of the output file, so in this case can be random every time
    fsCrypt.Write(salt, 0, salt.Length);

    CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write);

    FileStream fsIn = new FileStream(inputFile, FileMode.Open);

    //create a buffer (1mb) so only this amount will allocate in the memory and not the whole file
    byte[] buffer = new byte[1048576];
    int read;

    try
    {
        while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0)
        {
            Application.DoEvents(); // -> for responsive GUI, using Task will be better!
            cs.Write(buffer, 0, read);
        }

        // Close up
        fsIn.Close();
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: " + ex.Message);
    }
    finally
    {
        cs.Close();
        fsCrypt.Close();
    }
}

/// <summary>
/// Decrypts an encrypted file with the FileEncrypt method through its path and the plain password.
/// </summary>
/// <param name="inputFile"></param>
/// <param name="outputFile"></param>
/// <param name="password"></param>
private void FileDecrypt(string inputFile, string outputFile, string password)
{
    byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password);
    byte[] salt = new byte[32];

    FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
    fsCrypt.Read(salt, 0, salt.Length);

    RijndaelManaged AES = new RijndaelManaged();
    AES.KeySize = 256;
    AES.BlockSize = 128;
    var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
    AES.Key = key.GetBytes(AES.KeySize / 8);
    AES.IV = key.GetBytes(AES.BlockSize / 8);
    AES.Padding = PaddingMode.PKCS7;
    AES.Mode = CipherMode.CFB;

    CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read);

    FileStream fsOut = new FileStream(outputFile, FileMode.Create);

    int read;
    byte[] buffer = new byte[1048576];

    try
    {
        while ((read = cs.Read(buffer, 0, buffer.Length)) > 0)
        {
            Application.DoEvents();
            fsOut.Write(buffer, 0, read);
        }
    }
    catch (CryptographicException ex_CryptographicException)
    {
        Console.WriteLine("CryptographicException error: " + ex_CryptographicException.Message);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: " + ex.Message);
    }

    try
    {
        cs.Close();
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error by closing CryptoStream: " + ex.Message);
    }
    finally
    {
        fsOut.Close();
        fsCrypt.Close();
    }
}

Example 2: encrypt in C#

using System;
using System.IO;
using System.Security.Cryptography;

class Class1
{
    static void Main(string[] args)
    {
        //The key and IV must be the same values that were used
        //to encrypt the stream.
        byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
        byte[] iv = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
        try
        {
            //Create a file stream.
            FileStream myStream = new FileStream("TestData.txt", FileMode.Open);

            //Create a new instance of the default Aes implementation class
            Aes aes = Aes.Create();

            //Create a CryptoStream, pass it the file stream, and decrypt
            //it with the Aes class using the key and IV.
            CryptoStream cryptStream = new CryptoStream(
               myStream,
               aes.CreateDecryptor(key, iv),
               CryptoStreamMode.Read);

            //Read the stream.
            StreamReader sReader = new StreamReader(cryptStream);

            //Display the message.
            Console.WriteLine("The decrypted original message: {0}", sReader.ReadToEnd());

            //Close the streams.
            sReader.Close();
            myStream.Close();
        }
        //Catch any exceptions.
        catch
        {
            Console.WriteLine("The decryption failed.");
            throw;
        }
    }
}