Click here to Skip to main content
11,705,610 members (50,890 online)
Click here to Skip to main content

Encrypt/Decrypt Files in VB.NET (Using Rijndael)

, 4 Nov 2005 700.3K 23.2K 98
Rate this:
Please Sign up or sign in to vote.
How to encrypt and decrypt files using Rijndael.

Sample Image - EncryptFile.jpg

Introduction

This is a sample application that will encrypt and decrypt files in VB.NET using Rijndael Managed. I started this project because I had several files on my computer that I didn’t want accessible to anyone but me. Sure I could have downloaded a free encryption program off the net, but what fun would that be? So being the hobbyist that I am, I decided to create my own.

Background

Here are some brief descriptions of the cryptographic concepts relevant to this application. I am going to keep things as simple and basic as possible. If you want further details there is a ton of information on the web. Also check out “.NET Encryption Simplified” by: wumpus1 right here at Code Project. These descriptions are based on how the concepts are used in this application.

  1. The Key:

    The password used to encrypt/decrypt data.

  2. The IV:

    Initialization Vector. This is used to encrypt the first portion of the data to be encrypted.

  3. Rijndael:

    The algorithm used for encryption/decryption. In this application, Rijndael is using a 256 bit key and a 128 bit IV.

  4. SHA512 Hashing:

    This takes a string (the password) and transforms it into a fixed size (512 bits) of “encrypted data”. The same string will always “hash” into the same 512 bits of data.

Using the code

In this section I will cover the following:

  • Creating the Key
  • Creating the IV
  • Encryption and decryption
  • Changing file extensions
  • Putting it all together

My explanations will be brief because my code is heavily commented. Before we begin, we will need the following Imports statements:

Imports System
Imports System.IO
Imports System.Security
Imports System.Security.Cryptography

Now let's declare our global variables:

'*************************
'** Global Variables
'*************************

Dim strFileToEncrypt As String
Dim strFileToDecrypt As String
Dim strOutputEncrypt As String
Dim strOutputDecrypt As String
Dim fsInput As System.IO.FileStream
Dim fsOutput As System.IO.FileStream

Creating the Key

Of course, the most secure Key would be a randomly generated Key. But I prefer to make up my own. The following code is a function that will create a 256 bit Hashed Key from the user’s password. Here is what happens in the function:

  • The function receives a string (the password).
  • Converts the string to an array.
  • Converts the array to a byte.
  • Uses SHA512 to hash the byte.
  • Stores the first 256 bits of the hashed byte into a new byte (the key).
  • Returns the key.

For a more in-depth description, read the ‘comments' in the following code:

'*************************
'** Create A Key
'*************************

Private Function CreateKey(ByVal strPassword As String) As Byte()
    'Convert strPassword to an array and store in chrData.
    Dim chrData() As Char = strPassword.ToCharArray
    'Use intLength to get strPassword size.
    Dim intLength As Integer = chrData.GetUpperBound(0)
    'Declare bytDataToHash and make it the same size as chrData.
    Dim bytDataToHash(intLength) As Byte
    
    'Use For Next to convert and store chrData into bytDataToHash.
    For i As Integer = 0 To chrData.GetUpperBound(0)
        bytDataToHash(i) = CByte(Asc(chrData(i)))
    Next

    'Declare what hash to use.
    Dim SHA512 As New System.Security.Cryptography.SHA512Managed
    'Declare bytResult, Hash bytDataToHash and store it in bytResult.
    Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
    'Declare bytKey(31).  It will hold 256 bits.
    Dim bytKey(31) As Byte
    
    'Use For Next to put a specific size (256 bits) of 
    'bytResult into bytKey. The 0 To 31 will put the first 256 bits
    'of 512 bits into bytKey.
    For i As Integer = 0 To 31
        bytKey(i) = bytResult(i)
    Next

    Return bytKey 'Return the key.
End Function

Here is an alternate example of creating a Key without using SHA512 hashing:

Private Function CreateKey(ByVal strPassword As String) As Byte()
    Dim bytKey As Byte()
    Dim bytSalt As Byte() = System.Text.Encoding.ASCII.GetBytes("salt")
    Dim pdb As New PasswordDeriveBytes(strPassword, bytSalt)
        
    bytKey = pdb.GetBytes(32)

    Return bytKey 'Return the key.
End Function

Creating the IV

OK, so we used the first 256 bits of our hashed byte to create the key. We will use the next 128 bits of our hashed byte to create our IV. This way the key will be different from the IV. This function is almost identical to the previous one.

'*************************
'** Create An IV
'*************************

Private Function CreateIV(ByVal strPassword As String) As Byte()
    'Convert strPassword to an array and store in chrData.
    Dim chrData() As Char = strPassword.ToCharArray
    'Use intLength to get strPassword size.
    Dim intLength As Integer = chrData.GetUpperBound(0)
    'Declare bytDataToHash and make it the same size as chrData.
    Dim bytDataToHash(intLength) As Byte

    'Use For Next to convert and store chrData into bytDataToHash.
    For i As Integer = 0 To chrData.GetUpperBound(0)
        bytDataToHash(i) = CByte(Asc(chrData(i)))
    Next

    'Declare what hash to use.
    Dim SHA512 As New System.Security.Cryptography.SHA512Managed
    'Declare bytResult, Hash bytDataToHash and store it in bytResult.
    Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
    'Declare bytIV(15).  It will hold 128 bits.
    Dim bytIV(15) As Byte

    'Use For Next to put a specific size (128 bits) of bytResult into bytIV.
    'The 0 To 30 for bytKey used the first 256 bits of the hashed password.
    'The 32 To 47 will put the next 128 bits into bytIV.
    For i As Integer = 32 To 47
        bytIV(i - 32) = bytResult(i)
    Next

    Return bytIV 'Return the IV.
End Function

Here is an alternate example of creating an IV without using SHA512 hashing:

Private Function CreateIV(ByVal strPassword As String) As Byte()
    Dim bytIV As Byte()
    Dim bytSalt As Byte() = System.Text.Encoding.ASCII.GetBytes("salt")
    Dim pdb As New PasswordDeriveBytes(strPassword, bytSalt)

    bytIV = pdb.GetBytes(16)

    Return bytIV 'Return the IV.
End Function

Encryption and Decryption

Here is the meat and potatoes of the encryption/decryption process. This block of code has been modified from an article called “Tales from the Crypto” by Billy Hollis. Here is what happens in this procedure:

  • Define the enumeration for CryptoAction (encrypt/decrypt).
  • Begin with an encrypted/unencrypted file.
  • Use a FileStream object to open and read the file.
  • Use a CryptoStream object to perform encryption/decryption.
  • Use another FileStream object to write the encrypted/decrypted file.

For a more in-depth description read the ‘comments' in the following code:

'****************************
'** Encrypt/Decrypt File
'****************************

Private Enum CryptoAction
    'Define the enumeration for CryptoAction.
    ActionEncrypt = 1
    ActionDecrypt = 2
End Enum

Private Sub EncryptOrDecryptFile(ByVal strInputFile As String, _
                                 ByVal strOutputFile As String, _
                                 ByVal bytKey() As Byte, _
                                 ByVal bytIV() As Byte, _
                                 ByVal Direction As CryptoAction)
    Try 'In case of errors.
      
        'Setup file streams to handle input and output.
        fsInput = New System.IO.FileStream(strInputFile, FileMode.Open, _
                                              FileAccess.Read)
        fsOutput = New System.IO.FileStream(strOutputFile, _
                                               FileMode.OpenOrCreate, _
                                               FileAccess.Write)
        fsOutput.SetLength(0) 'make sure fsOutput is empty

        'Declare variables for encrypt/decrypt process.
        Dim bytBuffer(4096) As Byte 'holds a block of bytes for processing
        Dim lngBytesProcessed As Long = 0 'running count of bytes processed
        Dim lngFileLength As Long = fsInput.Length 'the input file's length
        Dim intBytesInCurrentBlock As Integer 'current bytes being processed
        Dim csCryptoStream As CryptoStream
        'Declare your CryptoServiceProvider.
        Dim cspRijndael As New System.Security.Cryptography.RijndaelManaged
        'Setup Progress Bar
        pbStatus.Value = 0
        pbStatus.Maximum = 100

        'Determine if ecryption or decryption and setup CryptoStream.
        Select Case Direction
            Case CryptoAction.ActionEncrypt
                csCryptoStream = New CryptoStream(fsOutput, _
                cspRijndael.CreateEncryptor(bytKey, bytIV), _
                CryptoStreamMode.Write)

            Case CryptoAction.ActionDecrypt
                csCryptoStream = New CryptoStream(fsOutput, _
                cspRijndael.CreateDecryptor(bytKey, bytIV), _
                CryptoStreamMode.Write)
        End Select

        'Use While to loop until all of the file is processed.
        While lngBytesProcessed < lngFileLength
            'Read file with the input filestream.
            intBytesInCurrentBlock = fsInput.Read(bytBuffer, 0, 4096)
            'Write output file with the cryptostream.
            csCryptoStream.Write(bytBuffer, 0, intBytesInCurrentBlock)
            'Update lngBytesProcessed
            lngBytesProcessed = lngBytesProcessed + _
                                    CLng(intBytesInCurrentBlock)
            'Update Progress Bar
            pbStatus.Value = CInt((lngBytesProcessed / lngFileLength) * 100)
        End While

        'Close FileStreams and CryptoStream.
        csCryptoStream.Close()
        fsInput.Close()
        fsOutput.Close()

Changing File Extensions

Basically, what we are doing here is taking the path name of the file to encrypt/decrypt and adding or removing an “.encrypt” extension. This is not really necessary for encrypting files, but I think it looks cool.

When encrypting a file we would add an “.encrypt” extension as follows:

'Setup the open dialog.
OpenFileDialog.FileName = ""
OpenFileDialog.Title = "Choose a file to encrypt"
OpenFileDialog.InitialDirectory = "C:\"
OpenFileDialog.Filter = "All Files (*.*) | *.*"

'Find out if the user chose a file.
If OpenFileDialog.ShowDialog = DialogResult.OK Then
    strFileToEncrypt = OpenFileDialog.FileName
    txtFileToEncrypt.Text = strFileToEncrypt

    Dim iPosition As Integer = 0
    Dim i As Integer = 0

    'Get the position of the last "\" in the OpenFileDialog.FileName path.
    '-1 is when the character your searching for is not there.
    'IndexOf searches from left to right.
    While strFileToEncrypt.IndexOf("\"c, i) <> -1
        iPosition = strFileToEncrypt.IndexOf("\"c, i)
        i = iPosition + 1
    End While

    'Assign strOutputFile to the position after the last "\" in the path.
    'This position is the beginning of the file name.
    strOutputEncrypt = strFileToEncrypt.Substring(iPosition + 1)
    'Assign S the entire path, ending at the last "\".
    Dim S As String = strFileToEncrypt.Substring(0, iPosition + 1)
    'Replace the "." in the file extension with "_".
    strOutputEncrypt = strOutputEncrypt.Replace("."c, "_"c)
    'The final file name.  XXXXX.encrypt
    txtDestinationEncrypt.Text = S + strOutputEncrypt + ".encrypt"

When decrypting a file we would remove the “.encrypt” extension as follows:

'Setup the open dialog.
OpenFileDialog.FileName = ""
OpenFileDialog.Title = "Choose a file to decrypt"
OpenFileDialog.InitialDirectory = "C:\"
OpenFileDialog.Filter = "Encrypted Files (*.encrypt) | *.encrypt"

'Find out if the user chose a file.
If OpenFileDialog.ShowDialog = DialogResult.OK Then
    strFileToDecrypt = OpenFileDialog.FileName
    txtFileToDecrypt.Text = strFileToDecrypt
    Dim iPosition As Integer = 0
    Dim i As Integer = 0
    'Get the position of the last "\" in the OpenFileDialog.FileName path.
    '-1 is when the character your searching for is not there.
    'IndexOf searches from left to right.

    While strFileToDecrypt.IndexOf("\"c, i) <> -1
        iPosition = strFileToDecrypt.IndexOf("\"c, i)
        i = iPosition + 1
    End While

    'strOutputFile = the file path minus the last 8 characters (.encrypt)
    strOutputDecrypt = strFileToDecrypt.Substring(0, _
                                            strFileToDecrypt.Length - 8)
    'Assign S the entire path, ending at the last "\".
    Dim S As String = strFileToDecrypt.Substring(0, iPosition + 1)
    'Assign strOutputFile to the position after the last "\" in the path.
    strOutputDecrypt = strOutputDecrypt.Substring((iPosition + 1))
    'Replace "_" with "."
    txtDestinationDecrypt.Text = S + strOutputDecrypt.Replace("_"c, "."c)

Keep in mind that the above code is geared towards my sample application.

Putting It All Together

OK, so this is where everything comes together with the “Encrypt” and “Decrypt” buttons. Basically what happens here is:

  • Variables are declared for the Key and IV.
  • The user’s password is passed to the CreateKey function.
  • The user’s password is passed to the CreateIV function.
  • The input path name, output path name, Key, IV, and CryptoAction are passed to the EncryptOrDecryptFile procedure.

Encrypting would go as follows:

'Declare variables for the key and iv.
'The key needs to hold 256 bits and the iv 128 bits.
Dim bytKey As Byte()
Dim bytIV As Byte()
'Send the password to the CreateKey function.
bytKey = CreateKey(txtPassEncrypt.Text)
'Send the password to the CreateIV function.
bytIV = CreateIV(txtPassEncrypt.Text)
'Start the encryption.
EncryptOrDecryptFile(strFileToEncrypt, txtDestinationEncrypt.Text, _
                     bytKey, bytIV, CryptoAction.ActionEncrypt)

Decrypting would go as follows:

'Declare variables for the key and iv.
'The key needs to hold 256 bits and the iv 128 bits.
Dim bytKey As Byte()
Dim bytIV As Byte()
'Send the password to the CreateKey function.
bytKey = CreateKey(txtPassDecrypt.Text)
'Send the password to the CreateIV function.
bytIV = CreateIV(txtPassDecrypt.Text)
'Start the decryption.
EncryptOrDecryptFile(strFileToDecrypt, txtDestinationDecrypt.Text, _
                     bytKey, bytIV, CryptoAction.ActionDecrypt)

Points of Interest

This application uses the Rijndael algorithm to encrypt and decrypt files. You could also use Data Encryption Standard (DES) or Triple DES to do the same. All you would need to change is the Key size, IV size and the Crypto Service Provider. I hope that you can have some fun with this code. Questions and comments are appreciated.

History

  • October 28, 2005: Posted.
  • October 31, 2005: File size issue fixed, thanks to Moonark.
  • November 1, 2005: Alternate examples of CreateKey/IV added, thanks to Vlad Tepes.
  • November 4, 2005: Array issue fixed, thanks to ccady.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Thad Van den Bosch
United States United States
I was introduced to VB.Net while serving in the U.S. Army Infantry. Since then I enjoy writing small applications in my spare time.

You may also be interested in...

Comments and Discussions

 
QuestionMessage Removed Pin
Member 117143072-Aug-15 19:38
memberMember 117143072-Aug-15 19:38 
QuestionUser Login Pin
Member62727-Apr-15 14:14
memberMember62727-Apr-15 14:14 
QuestionRegarding the same i want to give it as a minor project Pin
Member 1154137921-Mar-15 20:07
memberMember 1154137921-Mar-15 20:07 
QuestionRegarding the code and full project demo Pin
Member 1154137921-Mar-15 20:02
memberMember 1154137921-Mar-15 20:02 
QuestionCrypt all the files of a directory Pin
Member 1147112122-Feb-15 23:57
memberMember 1147112122-Feb-15 23:57 
QuestionVb.NET to JAVA Pin
Member 1089597610-Jan-15 5:57
memberMember 1089597610-Jan-15 5:57 
QuestionEmail Attached Pin
Member 108959769-Jan-15 12:23
memberMember 108959769-Jan-15 12:23 
QuestionThanks message and Java Code Rquested Pin
Member 108959769-Jan-15 12:18
memberMember 108959769-Jan-15 12:18 
QuestionI NEED YOUR HELP SIR Pin
omer bhutta30-Nov-14 23:29
memberomer bhutta30-Nov-14 23:29 
QuestionThank you for this article :) Pin
NavaneethaKrishnan A13-Nov-14 21:11
memberNavaneethaKrishnan A13-Nov-14 21:11 
SuggestionSimpler way to generate IV and Key Pin
1337Architect22-Aug-14 19:51
professional1337Architect22-Aug-14 19:51 
Questionauto encryption Pin
Member 1028014522-Aug-14 8:37
memberMember 1028014522-Aug-14 8:37 
General:) Pin
Widgets23-May-14 9:45
memberWidgets23-May-14 9:45 
QuestionOpen encrypted file without decrypting Pin
Ranganath Deshpande7-Jan-14 11:00
memberRanganath Deshpande7-Jan-14 11:00 
QuestionGood Pin
Member 850494129-Dec-13 16:23
memberMember 850494129-Dec-13 16:23 
Questioni forget the password is there anyway to retrieve my password Pin
michael nabil11-Aug-13 5:52
membermichael nabil11-Aug-13 5:52 
Questionhelllo.... Pin
Basiliso11-Jul-13 23:23
memberBasiliso11-Jul-13 23:23 
QuestionMy heart felt thanks... Pin
Member 1013340330-Jun-13 15:33
memberMember 1013340330-Jun-13 15:33 
QuestionRijndael cryptography to secure a text message or a text?? Pin
Evangeline Cristian Van Haven30-Jun-13 8:15
memberEvangeline Cristian Van Haven30-Jun-13 8:15 
GeneralMy vote of 5 Pin
Jayke Huempfner13-Jun-13 22:44
memberJayke Huempfner13-Jun-13 22:44 
QuestionGood Apps and Works Pin
sug1anto5-Mar-13 20:47
membersug1anto5-Mar-13 20:47 
Questionsir, i need your help Pin
dexter262-Mar-13 0:53
memberdexter262-Mar-13 0:53 
QuestionEncrypt large files! Pin
Iovany Garcia25-Sep-12 14:06
memberIovany Garcia25-Sep-12 14:06 
QuestionIt works. Pin
akboy200322-Sep-12 11:26
memberakboy200322-Sep-12 11:26 
Questionrijndael 128 Pin
anndi78921-Sep-12 23:02
memberanndi78921-Sep-12 23:02 
QuestionHow we reduse jpg file size? Pin
raj 198816-Aug-12 23:05
memberraj 198816-Aug-12 23:05 
GeneralMy vote of 5 Pin
Midnight Ahri17-May-12 15:54
memberMidnight Ahri17-May-12 15:54 
QuestionError 'Direction' cannot expose type 'CryptoAction' in namespace Pin
arun_ajay200011-Apr-12 2:39
memberarun_ajay200011-Apr-12 2:39 
QuestionHow can i call this function without browse? Pin
Farooq Pathan30-Sep-11 4:27
memberFarooq Pathan30-Sep-11 4:27 
QuestionI m getting this error while decrypting the encrypted object please help me..... Pin
ajinkya_bidkar28-Jun-11 18:24
memberajinkya_bidkar28-Jun-11 18:24 
GeneralMy vote of 5 Pin
mestrini22-Feb-11 2:31
membermestrini22-Feb-11 2:31 
GeneralMy vote of 5 Pin
jmnemonik21-Jan-11 0:36
memberjmnemonik21-Jan-11 0:36 
GeneralExcellent! Pin
David Fist7-Dec-10 7:50
memberDavid Fist7-Dec-10 7:50 
GeneralUsing the new Rfc2898DeriveBytes to get a key and IV Pin
Shadar426327-Sep-10 8:19
memberShadar426327-Sep-10 8:19 
QuestionCan anyone give a suggestion Pin
hang_em27-Sep-10 0:21
memberhang_em27-Sep-10 0:21 
Generalregarding decrpt tool Pin
mohitgupta2112-Jul-10 2:42
membermohitgupta2112-Jul-10 2:42 
Generalgood code Pin
xiongyingjun10-Jun-10 21:05
memberxiongyingjun10-Jun-10 21:05 
GeneralVbs script Pin
Member 468085520-Mar-10 7:07
memberMember 468085520-Mar-10 7:07 
GeneralMarvelous!!!!! Pin
RyanMaxie14-Oct-09 14:55
memberRyanMaxie14-Oct-09 14:55 
GeneralVery good application HOWEVER Pin
offroaderdan14-Oct-09 4:53
memberoffroaderdan14-Oct-09 4:53 
AnswerRe: Very good application HOWEVER Pin
Member 94759414-Dec-12 13:15
memberMember 94759414-Dec-12 13:15 
GeneralWrong password feedback message Pin
Fritz4421-Sep-09 12:34
memberFritz4421-Sep-09 12:34 
Questionshow me the encoding and chipering process Pin
unch13-Aug-09 15:13
memberunch13-Aug-09 15:13 
AnswerRe: show me the encoding and chipering process Pin
Thad Van den Bosch14-Aug-09 16:09
memberThad Van den Bosch14-Aug-09 16:09 
GeneralGreat Example! Pin
rkeslar6136-Aug-09 9:16
memberrkeslar6136-Aug-09 9:16 
GeneralRe: Great Example! Pin
Thad Van den Bosch14-Aug-09 16:10
memberThad Van den Bosch14-Aug-09 16:10 
GeneralTypo! Pin
_PolyGram_21-Jul-09 6:01
member_PolyGram_21-Jul-09 6:01 
GeneralRe: Typo! Pin
Thad Van den Bosch14-Aug-09 16:14
memberThad Van den Bosch14-Aug-09 16:14 
GeneralThank you so much Pin
_Khallaf18-Jul-09 14:48
member_Khallaf18-Jul-09 14:48 
GeneralRe: Thank you so much Pin
Thad Van den Bosch14-Aug-09 16:10
memberThad Van den Bosch14-Aug-09 16:10 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150819.1 | Last Updated 5 Nov 2005
Article Copyright 2005 by Thad Van den Bosch
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid