Triple-DES Key Obfuscation in VB.NET

Posted by Beau on Tuesday, August 17th, 2010 at 4:35 am

This is meant as a follow up to my previous post where I talked about the dangers of just leaving your keys laying around when you want to decrypt an XML file. Well, I devised just one solution that can help make your code a little harder to crack. This article will be a little easier to follow (I hope) if you read the last post, because this post is really a supplement to it.

If you look in the last article, we were writing the key we needed to decrypt to a simple little text file called sharedsampleKey.txt. Anyone who knows what’s what will be able to simply take your encrypted XML file and your key and write a little program to decrypt your data.

A triple-DES hash looks like a jumbled mess of 32 case-sensitive letters, numbers, and symbols, so, in the sharedsampleKey.txt file, we have a key that looks something like this: p4WyhV3GAAj3hG2PnXhfIDp5JGKJ6mqQ. Wouldn’t it be nice if we could make it just a little harder to read? Well you’re in luck, because there’s a couple ways we can do that.

The method I devised involves padding the key with some dummy keys, so that the would-be code-cracker would have to parse out the correct 32-character string from the garbage mess. But instead of writing out a few dummy keys and then sticking the real key on the end, or in some known place in the middle, I decided to cut the real key into pieces, to make it even harder to get the correct string. I know that sounds a little complicated, and it is, but hopefully looking at the code and reading the comments, it’ll make more sense:

 'this variable will hold our dummy key data
            Dim tDESkey As New TripleDESCryptoServiceProvider()
            'this will generate the real key we need to unlock the data
            Dim sharedkey As New TripleDESCryptoServiceProvider()
            'convert the key to a string
            Dim realkey As String = Convert.ToBase64String(sharedkey.Key)

            'open the file writer to write to a text file
            Dim writer1 As IO.StreamWriter = New IO.StreamWriter("C:\Temp\sharedsamplepaddedKey.txt")
            'convert the real key to a character array, so it'll be easier to slice the string up
            Dim ourkey() = realkey.ToCharArray

            'run a for loop with a step count of your choice
            '  I chose 15 to keep things simple
            For x = 0 To 15
                'generate a new key
                tDESkey.GenerateKey()
                'convert it to a string
                Dim str1 As String = Convert.ToBase64String(tDESkey.Key)
                'here I arbitrarily chose an iteration to insert the first half
                ' of my real key; remember how many iterations you used for later
                If x = 4 Then
                    'A nested for loop to write out the first 16 characters
                    For i = 0 To 15
                        writer1.Write(ourkey(i))
                    Next i
                    ' another arbitrary iteration number, a few cycles later
                ElseIf x = 8 Then
                    'start where we left off and write out the last 16 characters
                    For i = 16 To 31
                        writer1.Write(ourkey(i))
                    Next i
                Else
                    'otherwise, just write a dummy key
                    writer1.Write(str1)
                End If
                'continue the loop
            Next x
            'close the file writer
            writer1.Close()

If you go look at the sharedsamplepaddedKey.txt file, you’ll see a nice jumbled mess of code that’ll be harder to crack. But because we know our arbitrary positions that we inserted each half of the key, we can use the the String.Remove() method to cut through the junk characters and piece together our real string. We can do that by:

 'A variable to hold our final, real key
            Dim sharedkey As New TripleDESCryptoServiceProvider()

            'open the file with a streamreader
            Dim rd2 As IO.StreamReader = New IO.StreamReader("C:\Temp\sharedsamplepaddedKey.txt")
            'read the contents from the file into a string
            Dim testStr As String = rd2.ReadToEnd()
            'Console.WriteLine(testStr)
            'Here's where it gets a little tricky
            ' Assuming you used the code above, we wrote out 4 full dummy
            ' keys before we inserted the first half of the real one, and
            ' each key is 32 characters long. So starting from 0 (the very
            ' beginning of the line, we remove 128 characters (32 x 4 = 128)
            testStr = testStr.Remove(0, 128)
            'Now, we have the first half (16 characters) so we need to KEEP
            ' those and then cut away 3 more lines to get to the next half
            ' so we start at position 16 and cut away 96 more characters
            testStr = testStr.Remove(16, 96)
            'We have the full 32-character key! but we need to cut away the
            ' trailing 7 lines so we jump 32 characters in, and remove 224
            ' more pieces of junk
            testStr = testStr.Remove(32, 224)
            Console.WriteLine(testStr)
            'then we convert the string to a byte array...
            Dim bytedata() As Byte = Convert.FromBase64String(testStr)
            '...and set our key's value! Hooray!
            sharedkey.Key = bytedata

Refer to the previous article on how to use the key to decrypt the data.

Expanding the Obfuscation

This is a fairly simple way of going about things, and it still is crackable, but this way it’s harder to figure out what the real key is. But, you can make it even harder! You can split the real key up into as many pieces as you want, but it’s going to make your String.Remove()’s a bigger pain when trying to build the real key. You can pad it with a ton more dummy keys, or you could be tricky and start reversing parts of the real key; you’ll just have to remember all the steps you took to hide the real key, and the more you use, the sturdier your defenses. But the more you use, the more you have to remember, so it’s all really about how much trouble you want to go through to protect the data and your own personal paranoia. In the end, everything can be cracked, but it never hurts to make it harder to do so.

There may be a way easier or better way to do all of this, but this was still a fun exercise in Visual Basic.NET. Suggestions, pointers, and questions are welcome – I’m not really a VB’er by trade, and I love getting new info, but hopefully this is helpful to someone.

Tags: , , , ,

This entry was posted on Tuesday, August 17th, 2010 at 4:35 am and is filed under Visual Basic.NET. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply