Click here to Skip to main content
15,892,537 members
Articles / Programming Languages / C#

How To Use Rijndael to Encrypt Any File Easily?

Rate me:
Please Sign up or sign in to vote.
4.20/5 (7 votes)
2 Jul 2009CPOL1 min read 45K   2.2K   36   8
Encrypt any file easily
Screenshot of the tool, and the test procedures of the tool are as follows:

Image 1

Encrypt:

Image 2

Result after encrypting:

Image 3

Decrypt:

Image 4

Result after decrypting:

Image 5

Introduction

This article introduces how to use the Rijndael to encrypt any file, such as *.jpg, *.doc... and decrypt the encrypted file.

Background

I promised my friend to help her to program one encrypt & decrypt tool for the examination,^-^. I searched some articles, but without the implementation of Rijndael, so I decided to do the Rijndael with the help of the MSDN.

Using the Code

The whole code is in the attachment. You can download it if you prefer, or use it directly. Files in the attachment are as follows:

screenshot.jpg

Aes.cs is the implementation of the Rijndael, and the main functions are Cipher and InvCipher.

C#
public void Cipher(byte[] input, byte[] output)  // encipher 16-bit input
{
    // state = input
    this.State = new byte[4, Nb];  // always [4,4]
    for (int i = 0; i < (4 * Nb); ++i)
    {
        this.State[i % 4, i / 4] = input[i];
    }

    AddRoundKey(0);

    for (int round = 1; round <= (Nr - 1); ++round)  // main round loop
    {
        SubBytes();
        ShiftRows();
        MixColumns();
        AddRoundKey(round);
    }  // main round loop

    SubBytes();
    ShiftRows();
    AddRoundKey(Nr);

    for (int i = 0; i < (4 * Nb); ++i)
    {
        output[i] = this.State[i % 4, i / 4];
    }

}  // Cipher()

public void InvCipher(byte[] input, byte[] output)  // decipher 16-bit input
{
    // state = input
    this.State = new byte[4, Nb];  // always [4,4]
    for (int i = 0; i < (4 * Nb); ++i)
    {
        this.State[i % 4, i / 4] = input[i];
    }

    AddRoundKey(Nr);

    for (int round = Nr - 1; round >= 1; --round)  // main round loop
    {
        InvShiftRows();
        InvSubBytes();
        AddRoundKey(round);
        InvMixColumns();
    }  // end main round loop for InvCipher

    InvShiftRows();
    InvSubBytes();
    AddRoundKey(0);

    // output = state
    for (int i = 0; i < (4 * Nb); ++i)
    {
        output[i] = this.State[i % 4, i / 4];
    }

}  // InvCipher()
RijndaelFrm.cs: The window of encryption & decryption by the Rijndael and the two functions(Encrypt & Decrypt) in RijndaelFrm.cs called the IF of the class Aes for encryption and decryption. You can get detailed information from the class.
C#
private Boolean Encrypt(string cOpenFile,string cSaveFile,string cPassword)
{
    //check param
    if (("" == cOpenFile) ||
        ("" == cSaveFile) ||
        ("" == cPassword))
    {
        return false;
    }

    if (false == File.Exists(cOpenFile))
    {
        return false;
    }

    while (true == File.Exists(cSaveFile))
    {
        cSaveFile = Rename(cSaveFile);
    }

    byte[] plainText = new byte[MAX_BLOCK_LENGTH];
    byte[] cipherText = new byte[MAX_BLOCK_LENGTH];
    byte[] bzkey = new byte[MAX_KEY_LENGTH];

    //get password
    bzkey = Encoding.Unicode.GetBytes(cPassword);

    //get bytes from file
    FileStream fileStream = new FileStream(cOpenFile, FileMode.Open);
    fileStream.Seek(0, SeekOrigin.Begin);

    //get the file stream for save
    FileStream saveStream = new FileStream(cSaveFile, FileMode.Append);

    //set length of the file
    long lFileLength = fileStream.Length;
    //set position of the file
    long lPostion = fileStream.Position;

    //Read byte and Encrypt
    while (lPostion < lFileLength)
    {
        //Initialize  the buffer
        Initialize(plainText, MAX_BLOCK_LENGTH);

        long lHasRead = fileStream.Read(plainText, 0, MAX_BLOCK_LENGTH);
        if (0 >= lHasRead)
        {
            break;
        }
        //set current cursor position
        lPostion = fileStream.Position;

        //Encrypt
        Aes aes = new Aes(ekeySize, bzkey, eblockSize);

        //Initialize  the buffer
        Initialize(cipherText, MAX_BLOCK_LENGTH);

        aes.Cipher(plainText, cipherText);
        saveStream.Write(cipherText, 0, MAX_BLOCK_LENGTH);
    }

    saveStream.Close();
    fileStream.Close();
    return true;
}

private Boolean Decrypt(string cOpenFile, string cSaveFile, string cPassword)
{
    //check param
    if (("" == cOpenFile) ||
        ("" == cSaveFile) ||
        ("" == cPassword))
    {
        return false;
    }

    if (0 > cOpenFile.LastIndexOf(".aes"))
    {
        return false;
    }

    if (false == File.Exists(cOpenFile))
    {
        return false;
    }

    while (true == File.Exists(cSaveFile))
    {
        cSaveFile = Rename(cSaveFile);
    }

    byte[] plainText = new byte[MAX_BLOCK_LENGTH];
    byte[] cipherText = new byte[MAX_BLOCK_LENGTH];
    byte[] bzkey = new byte[MAX_KEY_LENGTH];

    //get password
    bzkey = Encoding.Unicode.GetBytes(cPassword);

    //get bytes from file
    FileStream fileStream = new FileStream(cOpenFile, FileMode.Open);
    fileStream.Seek(0, SeekOrigin.Begin);

    //get the file stream for save
    FileStream saveStream = new FileStream(cSaveFile, FileMode.Append);

    //set length of the file
    long lFileLength = fileStream.Length;
    //set position of the file
    long lPostion = fileStream.Position;

    //Read byte and Decrypt
    while (lPostion < lFileLength)
    {
        //Initialize  the buffer
        Initialize(plainText, MAX_BLOCK_LENGTH);

        long lHasRead = fileStream.Read(plainText, 0, MAX_BLOCK_LENGTH);
        if (0 >= lHasRead)
        {
            break;
        }
        //set current cursor position
        lPostion = fileStream.Position;

        //Encrypt
        Aes aes = new Aes(ekeySize, bzkey, eblockSize);

        //Initialize  the buffer
        Initialize(cipherText, MAX_BLOCK_LENGTH);
        //Decrypt
        aes.InvCipher(plainText, cipherText);
        saveStream.Write(cipherText, 0, MAX_BLOCK_LENGTH);
    }

    saveStream.Close();
    fileStream.Close();

    return true;
}

Or you can transform the aes.cs to your project, and call the IF as shown above. You can easily encrypt or decrypt any of your files.

Note

The form is only compatible with the password whose max length is 128 bits, but the algorithm of the aes is compatible with the password whose max length can be 128, 192 or 256 bits. The user can complete this, or I could complete it later.

History

  • 2009-06-20: First build ver. 1.01

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Pioneer
China China
Begin work with high-level programming language since 2008/09;
Master at the embedded system and firmware.
I'm glad to make friend with someone who likes the embedded system or IT.

O(∩_∩)O

Contact Me:
MSN:qxcjust@hotmail.com

Comments and Discussions

 
GeneralMy vote of 5 Pin
nghiemvanhung27-Aug-11 23:49
nghiemvanhung27-Aug-11 23:49 
Generalproblem password.. Pin
cover8517-Jun-11 6:24
cover8517-Jun-11 6:24 
GeneralMAX_BLOCK_LENGTH Pin
brodhol31-Aug-10 22:02
brodhol31-Aug-10 22:02 
Question[My vote of 2] Why do not you use the class System.Security.Cryptography.Aes? Pin
Iker Celorrio12-Jul-09 21:53
Iker Celorrio12-Jul-09 21:53 
AnswerRe: [My vote of 2] Why do not you use the class System.Security.Cryptography.Aes? Pin
qxcjust12-Jul-09 23:30
qxcjust12-Jul-09 23:30 
QuestionPassword working? Pin
pimb210-Jul-09 4:36
pimb210-Jul-09 4:36 
AnswerRe: Password working? Pin
qxcjust12-Jul-09 16:00
qxcjust12-Jul-09 16:00 
GeneralRe: Password working? Pin
shpile3-Jul-10 22:57
shpile3-Jul-10 22:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.