Return to
HomePage
Decrypt a file via a block cipher using AES (VB)
Summary
The purpose of this code is to demonstrate the proper use of a symmetric block cipher. This test case utilizes AES (Rijndael) which serves as the current NIST encryption standard.
Applies To
* .NET Framework 2.0
* VB
Objectives
* To provide confidentiality of files which are transmitted over insecure or untrusted communication channels.
* To provide confidentiality of files in storage until they are needed by a user or application
Scenarios
* Application developer desires confidentiality for files in storage or in transit.
Solution Example
Public Sub [DecryptFile(ByVal] [sInputFilename] As String, [ByVal] [sOutputFilename] As String, [ByVal] sKey As String, [ByVal] sIV As String)
' The default AES key size under the .NET framework is 256. The following
' call will create an AES crypto provider and create a random initialization
' vector and key. The crypto mode defaults to CBC ensuring the proper chaining
' of data to mitigate repetition of cipher text blocks.
Dim rijndaelAlg As Rijndael = Rijndael.Create()
'Set secret key For AES algorithm.
rijndaelAlg.Key = [ASCIIEncoding.ASCII.GetBytes(sKey)]
'Set initialization vector.
rijndaelAlg.IV = [ASCIIEncoding.ASCII.GetBytes(sIV)]
'Create a file stream to read the encrypted file back.
Dim fsCiphertext As [FileStream] = New [FileStream(sInputFilename,FileMode.Open,FileAccess.Read)]
'Create an AES decryptor
Dim aesdecrypt As [ICryptoTransform] = [rijndaelAlg.CreateDecryptor()]
'Create crypto stream set to read and do an AES decryption transform on incoming bytes.
Dim cipherstream As [CryptoStream] = New [CryptoStream(fsCiphertext,aesdecrypt,CryptoStreamMode.Read)]
'Write the contents of the decrypted file.
Dim fsPlaintext As [StreamWriter] = New [StreamWriter(sOutputFilename)]
fsPlaintext.Write(New [StreamReader(cipherstream).ReadToEnd())]
fsPlaintext.Flush()
fsCiphertext.Close()
fsPlaintext.Close()
End Sub
Problem Example
The following example demonstrates an implementation of a Decryption routine containing several common
secure coding issues.
Public [ProblematicFileDecrypt(ByVal] [sInputFilename] As String, [ByVal] [sOutputFilename] As String)
Dim rijndaelAlg As Rijndael = Rijndael.Create()
' Set secret key For AES algorithm.
rijndaelAlg.Key = ASCIIEncoding.ASCII.GetBytes("_A_SAMPLE_KEY_WE_USE_TO_ENCRYPT_")
' We don't use an IV because the book doesn't show us an example using a
' more secure, chained mode!
' rijndaelAlg.IV = ASCIIEncoding.ASCII.GetBytes("SAMPLEIV");
' Set encryption mode to an unchained value (because the book says so!)
rijndaelAlg.Mode = [CipherMode.ECB]
' Create a file stream to read the encrypted file back.
Dim fsCiphertext As [FileStream] = New [FileStream(sInputFilename,FileMode.Open,FileAccess.Read)]
' Create an AES decryptor
Dim aesdecrypt As [ICryptoTransform] = [rijndaelAlg.CreateDecryptor()]
'Create crypto stream set to read and do an AES decryption transform on incoming bytes.
Dim cipherstream As [CryptoStream] = New [CryptoStream(fsCiphertext,aesdecrypt,CryptoStreamMode.Read)]
'Write the contents of the decrypted file.
Dim fsPlaintext As [StreamWriter] = New [StreamWriter(sOutputFilename)]
fsPlaintext.Write(New [StreamReader(cipherstream).ReadToEnd())]
fsPlaintext.Flush()
fsCiphertext.Close()
fsPlaintext.Close()
End Sub
* Cleartext encryption key can be extracted by any user with access to the source code or compiled code
* Use of a weak encryption key, which can be brute-forced using a dictionary attack
* Insecure cipher mode (ECB), performs encryption of each blocks 128 bits independently with no
feedback into subsequent blocks as CBC and other chained modes do. An attacker can rearrange or replace
blocks with previous blocks they observe.
* ECB mode does not utilize an initialization vector, yielding the same encrypted value for each plaintext value. An attacker can thus observe patterns in the encrypted blocks and perform known plaintext attacks (Note: Initialization vectors need not remain secret however they should be random for each encrypted value of the plaintext)
Test Case
The following classes must be included in any project making use of the sample code provided above:
Imports System
Imports System.Text
Imports System.IO
Imports System.Security.Cryptography
The following test case demonstrates the use of the
DecryptFile function
Sub [Main(ByVal] args() As String)
' Test case for file encryption routines
Console.Out.WriteLine("Encrypting: " + args(0) + " to file: " + args(1))
[EncryptFile(args(0),] args(1), sKey, sIV)
Console.Out.WriteLine("Decrypting: " + args(1) + " to file: " + args(0) + ".new")
[DecryptFile(args(1),] args(0) + ".new", sKey, sIV)
End Sub
* sKey and sIV are retrieved from the
DataProtection API within Application code
Expected Result
Comparing the Decrypted file value with the original file text should yield the same text.
More Information
* Although AES defaults to 256-bit key sizes under the .NET framework, even under current cryptography standards, the default 128-bit key-size used by many crypto implementations is still considered secure.
* The test case assumes use of the
DataProtection API implemented within the user code to securely store and retrieve encryption keys.
Additional Resources
* Protecting keys using the DPAPI: http://msdn.microsoft.com/library/en-us/dnpag2/html/paght000005.asp
* Cryptography (.NET): http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGGuidelines0003.asp?frame=true#pagguidelines0003_cryptography
Attributes
* Applies To: .NET Framework 2.0, VB
* Category: Cryptography
* Author: George Gal
Return to
HomePage