|
|
Title | Encrypt and decrypt a file by using the triple DES algorithm in Visual Basic 2008 |
Description | This example shows how to encrypt and decrypt a file by using the triple DES algorithm in Visual Basic 2008. |
Keywords | Visual Basic 2008, VB 2008, encrypt, decrypt, cryptography, DES, triple DES |
Categories | Algorithms |
|
|
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.
|
|
|
|
|
|