Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleEncrypt and decrypt a file by using the triple DES algorithm in Visual Basic 2008
DescriptionThis example shows how to encrypt and decrypt a file by using the triple DES algorithm in Visual Basic 2008.
KeywordsVisual Basic 2008, VB 2008, encrypt, decrypt, cryptography, DES, triple DES
CategoriesAlgorithms
 
Subroutine CryptFile encrypts or decrypts a file. It starts by opening the input and output files. It then creates a TripleDESCryptoServiceProvider and queries the provider to see how big a key it can use. This program starts at 1024 bits and tests smaller and smaller key lengths until it finds one that is valid. The largest key allowed will depend on your operating system.

Next the program must make a key and initialization vector, a series of bytes used to initialize the provider. It calls subroutine MakeKeyAndIV, which is described shortly.

The program makes an appropriate cryptographic transform object to encrypt or decrypt the file. It uses the transform to make a CryptoStream attached to the output file. Now everything written via the CryptoStream gets encrypted or decrypted as it goes by. Finally the program reads blocks from the input file and writes them into the CryptoStream.

 
' Encrypt or decrypt a file, saving the results 
' in another file.
Private Sub CryptFile(ByVal password As String, ByVal _
    in_file As String, ByVal out_file As String, ByVal _
    encrypt As Boolean)
    ' Create input and output file streams.
    Using in_stream As New FileStream(in_file, _
        FileMode.Open, FileAccess.Read)
        Using out_stream As New FileStream(out_file, _
            FileMode.Create, FileAccess.Write)

            ' Make a triple DES service provider.
            Dim des_provider As New _
                TripleDESCryptoServiceProvider()

            ' Find a valid key size for this provider.
            Dim key_size_bits As Integer = 0
            For i As Integer = 1024 To 1 Step -1
                If des_provider.ValidKeySize(i) Then
                    key_size_bits = i
                    Exit For
                End If
            Next i
            Debug.Assert(key_size_bits > 0)

            ' Get the block size for this provider.
            Dim block_size_bits As Integer = _
                des_provider.BlockSize

            ' Generate the key and initialization vector.
            Dim key As Byte() = Nothing
            Dim iv As Byte() = Nothing
            Dim salt As Byte() = {&H0, &H0, &H1, &H2, &H3, _
                &H4, &H5, &H6, &HF1, &HF0, &HEE, &H21, _
                &H22, &H45}
            MakeKeyAndIV(password, salt, key_size_bits, _
                block_size_bits, key, iv)

            ' Make the encryptor or decryptor.
            Dim crypto_transform As ICryptoTransform
            If encrypt Then
                crypto_transform = _
                    des_provider.CreateEncryptor(key, iv)
            Else
                crypto_transform = _
                    des_provider.CreateDecryptor(key, iv)
            End If

            ' Attach a crypto stream to the output stream.
            ' Closing crypto_stream sometimes throws an
            ' exception if the decryption didn't work
            ' (e.g. if we use the wrong password).
            Try
                Using crypto_stream As New _
                    CryptoStream(out_stream, _
                    crypto_transform, _
                    CryptoStreamMode.Write)
                    ' Encrypt or decrypt the file.
                    Const BLOCK_SIZE As Integer = 1024
                    Dim buffer(BLOCK_SIZE) As Byte
                    Dim bytes_read As Integer
                    Do
                        ' Read some bytes.
                        bytes_read = in_stream.Read(buffer, _
                            0, BLOCK_SIZE)
                        If bytes_read = 0 Then Exit Do

                        ' Write the bytes into the
                        ' CryptoStream.
                        crypto_stream.Write(buffer, 0, _
                            bytes_read)
                    Loop

                    ' Close the streams.
                    crypto_stream.Flush()
                    crypto_stream.Close()
                End Using ' crypto_stream 
            Catch ex As Exception
            End Try

            crypto_transform.Dispose()
            in_stream.Close()
            out_stream.Close()
        End Using ' out_stream
    End Using ' in_stream
End Sub
 
Subroutine MakeKeyAndIV takes a password and uses it to generate a key and initialization vector. It creates a new Rfc2898DeriveBytes object generate a bunch of "random" bytes from the password. It calls the object's GetBytes method to generate the bytes it needs for the key and initialization vector.

The salt is a series of bytes chosen to make it harder for an attacker to build a dictionary of key/password pairs and it can be just about anything that's sort of random. The 1000 in the Rfc2898DeriveBytes constructor tells the class how many times to iterate the RFC 2898 algorithm to generate the bytes. Microsoft recommends that this parameter be at least 1000.

 
' Use the password to generate key bytes.
Private Sub MakeKeyAndIV(ByVal password As String, ByVal _
    salt() As Byte, ByVal key_size_bits As Integer, ByVal _
    block_size_bits As Integer, ByRef key As Byte(), ByRef _
    iv As Byte())
    Dim derive_bytes As New Rfc2898DeriveBytes( _
        password, salt, 1000)

    key = derive_bytes.GetBytes(key_size_bits \ 8)
    iv = derive_bytes.GetBytes(block_size_bits \ 8)
End Sub
 
When you click the first button, the program reads a plaintext file, encrypts it, and displays the result, which looks like gibberish.

When you click the second button, the program reads the encrypted file, descrypts it, and displays the result, which should look like the original text.

The algorithms used are pretty good so if you change a single character in the password by even a single letter (for example, change "a" to "b") and then click the decryption button, the result will still look like gibberish. You need to get the password exactly correct to learn anything about the message.

 
 
Copyright © 1997-2006 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated