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
Microsoft Communities