Return to
HomePage
Decrypt a string via a block cipher using 3DES (VB.NET)
Applies To
* .NET Framework 2.0
* VB.NET
Summary
The purpose of this code is to demonstrate the proper use of a symmetric block cipher to decrypt strings of text within an application. This code sample demonstrates the use of Triple DES, which should primarily be used for backwards compatibility with other applications and replaced with AES in newer implementations of code.
Objectives
* To provide confidentiality of data which is transmitted over insecure or untrusted communication channels.
* To provide confidentiality of data in storage until it is needed by a user or application
Scenarios
* Application developer desires confidentiality for data in storage or in transit.
* 3DES should only be used in implementations which require backwards compatibility for interaction with applications that do not implement the new NIST encryption standard, AES.
Solution Example
Public Function [DecryptString(ByVal] ciphertext As String, [ByVal] sKey() As Byte, [ByVal] sIV() As Byte) As String
' The default 3DES key size under the .NET framework is 192 (168). The following
' call will create a 3DES 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 tdes As [TripleDESCryptoServiceProvider] = [CType(TripleDESCryptoServiceProvider.Create(),] [TripleDESCryptoServiceProvider)]
'Set secret key For 3DES algorithm.
tdes.Key = sKey
'Set initialization vector.
tdes.IV = sIV
'Create a memorystream to which we'll decrypt our input string
Dim ms As [MemoryStream] = New [MemoryStream()]
Dim ecs As [CryptoStream] = New [CryptoStream(ms,tdes.CreateDecryptor(),CryptoStreamMode.Write)]
'Because the input string is passed in as a Base64 encoded value we decode prior writing to
'the decryptor stream.
[ecs.Write(Convert.FromBase64String(ciphertext),] 0, [Convert.FromBase64String(ciphertext).Length)]
ecs.Close()
Return [ASCIIEncoding.ASCII.GetString(ms.ToArray())]
End Function
Problem Example
The following example demonstrates an implementation of a Decryption routine containing several common secure coding issues.
Public Function [ProblematicDecryptString(ByVal] ciphertext As String) As String
Dim tdes As [TripleDESCryptoServiceProvider] = [CType(TripleDESCryptoServiceProvider.Create(),] [TripleDESCryptoServiceProvider)]
'Set secret key For 3DES algorithm.
tdes.Key = ASCIIEncoding.ASCII.GetBytes("ASAMPLEKEYWEUSETOENCRYPT")
'We don't use an IV because the book doesn't show us an example using a
'more secure, chained mode!
' tdes.IV = ASCIIEncoding.ASCII.GetBytes("SAMPLEIV");
'Set encryption mode to an unchained value (because the book says so!)
tdes.Mode = [CipherMode.ECB]
'Create a memorystream to which we'll decrypt our input string
Dim ms As [MemoryStream] = New [MemoryStream()]
Dim ecs As [CryptoStream] = New [CryptoStream(ms,tdes.CreateDecryptor(),CryptoStreamMode.Write)]
'Because the input string is passed in as a Base64 encoded value we decode prior writing to
'the decryptor stream.
[ecs.Write(Convert.FromBase64String(ciphertext),] 0, [Convert.FromBase64String(ciphertext).Length)]
ecs.Close()
Return [ASCIIEncoding.ASCII.GetString(ms.ToArray())]
End Function
* Cleartext encryption key can be extracted by any user with access to the source code or compiled code
* Use of a weak encryption (non-random) key, which can be brute-forced using a dictionary attack
* Insecure cipher mode (ECB), performs encryption of each block 64 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
DecryptString function
Sub [Main(ByVal] args() As String)
Dim enc As String,p2 As String,probenc As String,probp2 As String = Nothing
Dim tdes As [TripleDESCryptoServiceProvider] = [CType(TripleDESCryptoServiceProvider.Create(),] [TripleDESCryptoServiceProvider)]
' Test case for string encryption routines
Dim p1 As String = "the quick brown fox jumped over the lazy dog"
' Run our test case multiple times to demonstrate different IV / encrypted text for each
' iteration in when using proper crypto modes.
Console.Out.WriteLine("Solution test cases - notice varied output for static input")
Console.Out.WriteLine("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
Dim i As Integer
For i = 0 To 5- 1 Step i + 1
tdes.GenerateIV()
enc = [EncryptString(p1,] tdes.Key, tdes.IV)
Console.WriteLine("Encrypted text #{0}: " + enc, i)
p2 = [DecryptString(enc,] tdes.Key, tdes.IV)
Console.WriteLine("Plaintext #{0}: " + p2, i)
If Not p1.Equals(p2) Then
Console.Error.WriteLine("Decryption failed")
End If
Next
' Now run out problem test cases
Console.Out.WriteLine("Problem test cases - notice repetitive encrypted value")
Console.Out.WriteLine("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
Dim i As Integer
For i = 0 To 5- 1 Step i + 1
probenc = [ProblematicEncryptString(p1)]
probp2 = [ProblematicDecryptString(probenc)]
Console.WriteLine("Encrypted text #{0}: " + probenc, i)
Console.WriteLine("Plaintext #{0}: " + probp2, i)
Next
End Sub
* In this test case 3DES encryption keys and initialization vectors are chosen at random during the call to
TripleDESCryptoServiceProvider.Create(). * In a real-world implementation Key and IV should be retrieved from the Data Protection API within application code please refer to code sample demonstrating use of Data Protection API.
Expected Result
Solution test cases - notice varied output for static input
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Encrypted text #0:
f9n80d72AC1oD2b9a8yux/66UKaquzQLvQIV0A5xmtqded6hOKY5WFmcqtXOa0KH Plaintext #0: the quick brown fox jumped over the lazy dog
Encrypted text #1:
jloSmkMYW7TWXgnNKiNw/JCzzjIwm1K9DeyaFBbMfO9IOMMFcg9s0x917Bm0mBgg Plaintext #1: the quick brown fox jumped over the lazy dog
Encrypted text #2: zpRBQWz8ntpONAS+4tJKgEC88ntgj5esTizWUH4h9sQKkZDxxJ4qM6Y9yEugGH8c
Plaintext #2: the quick brown fox jumped over the lazy dog
Encrypted text #3:
4ssPSATxEbOBucRtbDcHq7SLurzknsZijpcMTg0puMthnPmI93mrbRQgfvOzbJEk Plaintext #3: the quick brown fox jumped over the lazy dog
Encrypted text #4: sxKZ3VDJP6SZw/IwznpH1VgR
rEYozcsntVJ6pnw75YqD7xb/WW3
3xeT4Q7Pf Plaintext #4: the quick brown fox jumped over the lazy dog
Problem test cases - notice repetitive encrypted value
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Encrypted text #0: z
0N6RlMZ2FLwaSQLDkyIHaxEsirAX68xE2cwZcHqh2CyE1zjjoGfMSTnnxOIVO
Plaintext #0: the quick brown fox jumped over the lazy dog
Encrypted text #1: z
0N6RlMZ2FLwaSQLDkyIHaxEsirAX68xE2cwZcHqh2CyE1zjjoGfMSTnnxOIVO
Plaintext #1: the quick brown fox jumped over the lazy dog
Encrypted text #2: z
0N6RlMZ2FLwaSQLDkyIHaxEsirAX68xE2cwZcHqh2CyE1zjjoGfMSTnnxOIVO
Plaintext #2: the quick brown fox jumped over the lazy dog
Encrypted text #3: z
0N6RlMZ2FLwaSQLDkyIHaxEsirAX68xE2cwZcHqh2CyE1zjjoGfMSTnnxOIVO
Plaintext #3: the quick brown fox jumped over the lazy dog
Encrypted text #4: z
0N6RlMZ2FLwaSQLDkyIHaxEsirAX68xE2cwZcHqh2CyE1zjjoGfMSTnnxOIVO
Plaintext #4: the quick brown fox jumped over the lazy dog
More Information
* 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