Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

HOME CONTENT INQUIRIES LANGUAGE: EN LOGIN 

Enter your search here... 

RELATED ARTICLES - C#

How to retrieve the amount of memory used within


your own C# WinForms Application
JANUARY 12TH 2020
C#

How to implement a Copy, Cut and Paste Context


Menu over a Rich Text Box in WinForms C#
DECEMBER 12TH 2019
C#

How to encrypt and decrypt files using the AES encryption algorithm in C#
JUNE 13TH 2017  70.1K  21 COMMENTS
How to allow only plain text inside a RichTextBox
in your C# WinForms Application
DECEMBER 9TH 2019
If the les of your users contain sensitive information, you can encrypt it so C#

that no one can open that le but the user itself. Encrypting your  les
makes them di cult for anyone to access and read without your password.
How to retrieve the RAM amount available on the
If you're into the encryption theme in your project, we'll show you in this System in WinForms with C#
article how to encrypt and decrypt les using the AES algorithm easily. AUGUST 26TH 2019
C#

Note
How to retrieve (list) the titles and process id of all
the opened applications in the taskbar of Windows
This article shows you a way to encrypt and decrypt easily and quickly les with C# in WinForms
using simple methods like encrypt and decrypt. They're the result of a AUGUST 22ND 2019

recopilation of information from di erent sources as Stack Over ow,


C#

Security Exchange and the o cial MSDN website.

1. Import required types ADVERTISE IN OUR CODE WORLD

In order to handle the AES encryption algorithm on your project to encrypt


and decrypt les, import the 2 following required types:

using System.Security.Cryptography;
using System.Runtime.InteropServices;

The reference to InteropServices in the top of your class will allow you to
use later the DllImport method in our class.

2. Create encryption and decryption methods


You will need to add the following 3 methods to your class (or create them
in a new class and then import them in yours):

GenerateRandomSalt: this method creates a random salt. This function is


customizable and you can modify it to create your own salt if you need
to.
FileEncrypt: this method encrypts an existent le with a plain
password.
FileDecrypt: this method decrypts a previously encrypted le with the
FileEncrypt method using the plain password as argument.
ZeroMemory: this method will be used to remove the password from the
memory, increasing the security of the encryption. It's not necessary,
however recomendable to use.

The method will be used and explained in the step #3, for now, copy and
include the methods in your project:

price drop

price drop price drop

FOLLOW US ON YOUR FAVORITE SOCIAL


NETWORK
BE SURE TO JOIN OUR GIVEAWAYS TO WIN SOMETHING
AWESOME OCASIONALLY 

  
LIKE US FOLLOW US STAR US ON
GITHUB

  
SUBSCRIBE SUBSCRIBE FOLLOW US
// Call this function to remove the key from memory after
[DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
public static extern bool ZeroMemory(IntPtr Destination, int

/// <summary>
/// Creates a random salt that will be used to encrypt your
/// </summary>
/// <returns></returns>
public static byte[] GenerateRandomSalt()
{
byte[] data = new byte[32];

using (RNGCryptoServiceProvider rng = new RNGCryptoServ


{
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-encry

//generate random salt


byte[] salt = GenerateRandomSalt();

//create output file name


FileStream fsCrypt = new FileStream(inputFile + ".aes",

//convert password string to byte arrray


byte[] passwordBytes = System.Text.Encoding.UTF8.GetByte

//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-ne
//"What it does is repeatedly hash the user password alo
var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);

//Cipher modes: http://security.stackexchange.com/quest


AES.Mode = CipherMode.CFB;

// write salt to the begining of the output file, so in


fsCrypt.Write(salt, 0, salt.Length);

CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateE

FileStream fsIn = new FileStream(inputFile, FileMode.Ope

//create a buffer (1mb) so only this amount will allocat


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

try
{
while ((read = fsIn.Read(buffer, 0, buffer.Length))
{
Application.DoEvents(); // -> for responsive GU
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 t
/// </summary>
/// <param name="inputFile"></param>
/// <param name="outputFile"></param>
/// <param name="password"></param>
private void FileDecrypt(string inputFile, string outputFile
{
byte[] passwordBytes = System.Text.Encoding.UTF8.GetByte
byte[] salt = new byte[32];

FileStream fsCrypt = new FileStream(inputFile, FileMode


fsCrypt.Read(salt, 0, salt.Length);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50
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.CreateDe

FileStream fsOut = new FileStream(outputFile, FileMode.C

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

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

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

They're not necessarily perfect and they can (and need to) be modi ed to
handle more exceptions in case they appear and how you work with your
application.
3. Using the methods
From the required methods, you will only need to use 2 of them (FileEncrypt
and FileDecrypt) obviously and 1 of them optional, the fourth
(GenerateRandomSalt) is used internally by the FileEncrypt method.

Encrypt File
Encrypt a le using the FileEncrypt method that expects as rst argument
the path to the le that will be encrypted and as second argument the
password that will be used to encrypt it. The password can be used to
decrypt the le later. To make everything right, we recommend you to
delete the password from the memory using the ZeroMemory method. Call
this function to remove the key from memory after use for security
purposes:

string password = "ThePasswordToDecryptAndEncryptTheFile";

// For additional security Pin the password of your files


GCHandle gch = GCHandle.Alloc(password, GCHandleType.Pinned

// Encrypt the file


FileEncrypt(@"C:\Users\username\Desktop\wordFileExample.doc

// To increase the security of the encryption, delete the g


ZeroMemory(gch.AddrOfPinnedObject(), password.Length * 2);
gch.Free();

// You can verify it by displaying its value later on the co


Console.WriteLine("The given password is surely nothing: " +

The FileEncrypt method will generate a le in the same directory of the


original le with the aes extension (e.g wordFileExample.doc).

Decrypt File
To decrypt the le, we'll follow the same process but using FileDecrypt
instead. This method expects as rst argument the path to the encrypted
le and as second argument the path where the decrypted le should be
placed. As third argument you need to provide the string that was used to
encrypt the le originally:
string password = "ThePasswordToDecryptAndEncryptTheFile";

// For additional security Pin the password of your files


GCHandle gch = GCHandle.Alloc(password, GCHandleType.Pinned

// Decrypt the file


FileDecrypt(@"C:\Users\sdkca\Desktop\example.doc.aes", @"C:

// To increase the security of the decryption, delete the u


ZeroMemory(gch.AddrOfPinnedObject(), password.Length * 2);
gch.Free();

// You can verify it by displaying its value later on the co


Console.WriteLine("The given password is surely nothing: " +

Final notes
The encryption/decryption process is memory consumming and take
time so it's recommendable to run those tasks in another thread to
prevent your main UI from freezing.
The extension aes can be changed for the extension that you want.

Happy coding !

 E-mail  Tweet  Like  Share  Pin it

 WhatsApp

Carlos Delgado

 

Interested in programming since he was 14 years old, Carlos is a self-taught programmer


and founder and author of most of the articles at Our Code World.

THIS COULD INTEREST YOU


    
BECOME A MORE SOCIAL PERSON

ALSO ON OUR CODE WORLD

7 months ago • 1 comment 4 months ago • 1 comment 7 months ago • 1 comment

How to solve Visual How CRM Boosts IT How to detect if the use
Studio Code can't be … Companies Rates prefers a light or dark …

Our Code World Comment Policy


Our Comments Section is open to every developer, so you can contribute (even
code) to the main idea of the Article.
Please read our Comment Policy before commenting.

21 Comments Our Code World 🔒 Disqus' Privacy Policy 


1 Login

 Recommend t Tweet f Share Sort by Best

J i th di i

OUR CODE WORLD LEGAL ABOUT US

Our Code World is a free blog about programming, where you will nd Privacy Policy About
solutions to simple and complex tasks of your daily life as a developer. Comments Policy Advertise with us

Authors

Contact

Write for us
ADVERTISING  

You might also like