AES Encrypt String in VB.NET

I have a program based in Visual Basic 2010.

I want to use a custom keyword and AES encryption to generate registration keys on our company website, that will unlock the software regardless of whether or not the software is connected to the internet.

To do this, I want to encrypt certain user information (and a validation code) into an AES encrypted string using a utility I'll build on my website. Then, I want my program to decrypt the string into the user information and validation code, then use that information to validate the registration key.

Which brings me to the question - how do I encrypt and decrypt a string in AES programatically? Is there a code template I can use somewhere, or a built in method?


A quick Google Search brings up the following functions: I've not tested whether the output they produce is correct, however they do appear to compile correctly.

Public Function AES_Encrypt(ByVal input As String, ByVal pass As String) As String
        Dim AES As New System.Security.Cryptography.RijndaelManaged
        Dim Hash_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
        Dim encrypted As String = ""
        Try
            Dim hash(31) As Byte
            Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
            Array.Copy(temp, 0, hash, 0, 16)
            Array.Copy(temp, 0, hash, 15, 16)
            AES.Key = hash
            AES.Mode = Security.Cryptography.CipherMode.ECB
            Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
            Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(input)
            encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
            Return encrypted
        Catch ex As Exception
        End Try
    End Function

Public Function AES_Decrypt(ByVal input As String, ByVal pass As String) As String
        Dim AES As New System.Security.Cryptography.RijndaelManaged
        Dim Hash_AES As New System.Security.Cryptography.MD5CryptoServiceProvider
        Dim decrypted As String = ""
        Try
            Dim hash(31) As Byte
            Dim temp As Byte() = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass))
            Array.Copy(temp, 0, hash, 0, 16)
            Array.Copy(temp, 0, hash, 15, 16)
            AES.Key = hash
            AES.Mode = Security.Cryptography.CipherMode.ECB
            Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
            Dim Buffer As Byte() = Convert.FromBase64String(input)
            decrypted = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
            Return decrypted
        Catch ex As Exception
        End Try
    End Function

Sourced from: http://www.l33thackers.com/Thread-VB-NET-AES-Encryption


Edit: Thanks to Artjom B. for notifying me for a mistake in decryption of AES-CBC that occured due to my false assumption that the IV strings always end with == (in Base64) which is wrong. Thanks to Kanky for bringing this topic up and thanks to Misery for offering a solution to it in this link. Note that I didn't check his/her fix myself, but hopefully it is correct.

Below are two solutions for encrypting strings with AES. First one uses CBC mode with an auto-generated IV and is more secure. The use of IV with CBC mode ensures that even the same plaintext-key pairs result in distinct ciphertexts and thus makes it more secure. Second one uses ECB more and shouldn't be used for repetitive plaintext encryption. AES.Key is generated by hashing the input key string with SHA256; so you don't have to worry about pseudorandomness of your key.

This one is AES-CBC. IV is auto-generated by the built-in function and concatenated with the ciphertext and returned as the output of the encryption algorithm. Decryption algorithm splits this concatenated text to recover the IV and the actual ciphertext.

Private Function AESE(ByVal plaintext As String, ByVal key As String) As String
    Dim AES As New System.Security.Cryptography.RijndaelManaged
    Dim SHA256 As New System.Security.Cryptography.SHA256Cng
    Dim ciphertext As String = ""
    Try
        AES.GenerateIV()
        AES.Key = SHA256.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(key))

        AES.Mode = Security.Cryptography.CipherMode.CBC
        Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
        Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(plaintext)
        ciphertext = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))

       Return Convert.ToBase64String(AES.IV) & Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))

    Catch ex As Exception
        Return ex.Message
    End Try
End Function

Private Function AESD(ByVal ciphertext As String, ByVal key As String) As String
    Dim AES As New System.Security.Cryptography.RijndaelManaged
    Dim SHA256 As New System.Security.Cryptography.SHA256Cng
    Dim plaintext As String = ""
    Dim iv As String = ""
    Try
        Dim ivct = ciphertext.Split({"=="}, StringSplitOptions.None)
        iv = ivct(0) & "=="
        ciphertext = If(ivct.Length = 3, ivct(1) & "==", ivct(1))

        AES.Key = SHA256.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(key))
        AES.IV = Convert.FromBase64String(iv)
        AES.Mode = Security.Cryptography.CipherMode.CBC
        Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
        Dim Buffer As Byte() = Convert.FromBase64String(ciphertext)
        plaintext = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length))
        Return plaintext
    Catch ex As Exception
        Return ex.Message
    End Try
End Function

This one below is AES-ECB mode. It doesn't use an IV. The same plaintexts always result in the same ciphertexts (under the same key of course) and vice versa.

Private Function AESE(ByVal input As Byte(), ByVal key As String) As Byte()
    Dim AES As New System.Security.Cryptography.RijndaelManaged
    Dim SHA256 As New System.Security.Cryptography.SHA256Cng
    Dim ciphertext As String = ""
    Try
        AES.Key = SHA256.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(key))
        AES.Mode = Security.Cryptography.CipherMode.ECB
        Dim DESEncrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateEncryptor
        Dim Buffer As Byte() = input
        Return DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
    Catch ex As Exception
    End Try
End Function

Private Function AESD(ByVal input As Byte(), ByVal key As String) As Byte()
    Dim AES As New System.Security.Cryptography.RijndaelManaged
    Dim SHA256 As New System.Security.Cryptography.SHA256Cng
    Try
        AES.Key = SHA256.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(key))
        AES.Mode = Security.Cryptography.CipherMode.ECB
        Dim DESDecrypter As System.Security.Cryptography.ICryptoTransform = AES.CreateDecryptor
        Dim Buffer As Byte() = input
        Return DESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
    Catch ex As Exception
    End Try
End Function

Below are two examples for AES and 3DES encryption. These use byte arrays as the input and output but you can easily modify to handle strings. As a good practice you should always generate the initialization vector (IV) and prepend it to the output file for decrypting. This helps protect your KEY from brute force attacks. It's also better to use CBC rather than EBC for the cipher mode.

Imports System.Security.Cryptography
Imports System.Text

Public Class CAes
    '************************************************************************************************
    'Functions for AES Encryption
    '************************************************************************************************
    Public Function AES_Encrypt(ByVal value As Byte(), ByVal key As String) As Byte()
        Dim AES As New RijndaelManaged
        Dim SHA256 As New SHA256Cng
        Dim output() As Byte

        AES.GenerateIV()
        Dim iv() As Byte = AES.IV
        AES.Key = SHA256.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key))

        AES.Mode = CipherMode.CBC
        Dim AESEncrypter As ICryptoTransform = AES.CreateEncryptor
        Dim Buffer As Byte() = value
        output = AESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)

        'Copy the IV as the first 16 bytes of the output then copy encrypted bytes
        Dim ivAndOutput(output.Length - 1 + 16) As Byte
        Array.Copy(iv, ivAndOutput, 16)
        Array.Copy(output, 0, ivAndOutput, 16, output.Length)

        Return ivAndOutput

    End Function

    Public Function AES_Decrypt(ByVal value As Byte(), ByVal key As String) As Byte()
        Dim AES As New RijndaelManaged
        Dim SHA256 As New SHA256Cng
        Dim output() As Byte
        Dim iv(15) As Byte
        Dim Buffer(value.Length - 1 - 16) As Byte

        'Extract first 16 bytes of input stream as IV.  Copy remaining bytes into encrypted buffer
        Array.Copy(value, iv, 16)
        Array.Copy(value, 16, Buffer, 0, value.Length - 16)

        AES.Key = SHA256.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key))
        AES.IV = iv
        AES.Mode = CipherMode.CBC
        Dim AESDecrypter As ICryptoTransform = AES.CreateDecryptor
        output = AESDecrypter.TransformFinalBlock(Buffer, 0, Buffer.Length)
        Return output

    End Function
End Class

Public Class C3Des

    '************************************************************************************************
    'Functions for 3DES Encryption
    '************************************************************************************************
    Public Function DES_Encrypt(ByVal value As Byte(), ByVal key As String) As Byte()
        Dim m As MD5 = New MD5CryptoServiceProvider
        Dim d As TripleDES = New TripleDESCryptoServiceProvider
        Dim encryptBytes() As Byte
        d.Key = m.ComputeHash(Encoding.Unicode.GetBytes(key))
        d.GenerateIV()
        Dim c As ICryptoTransform = d.CreateEncryptor
        Dim input() As Byte = value
        encryptBytes = c.TransformFinalBlock(input, 0, input.Length)
        Dim outBytes(encryptBytes.Length + d.IV.Length - 1) As Byte
        Array.Copy(d.IV, outBytes, d.IV.Length)
        Array.Copy(encryptBytes, 0, outBytes, 8, encryptBytes.Length)
        Return outBytes
    End Function

    Public Function DES_Decrypt(ByVal value As Byte(), ByVal key As String) As Byte()
        Dim m As MD5 = New MD5CryptoServiceProvider
        Dim d As TripleDES = New TripleDESCryptoServiceProvider
        Dim encryptBytes(value.Length - 9), iv(7) As Byte
        Array.Copy(value, 0, iv, 0, 8)
        Array.Copy(value, 8, encryptBytes, 0, value.Length - 8)
        d.Key = m.ComputeHash(Encoding.Unicode.GetBytes(key))
        d.IV = iv
        Dim b As Byte() = encryptBytes
        Dim c As ICryptoTransform = d.CreateDecryptor
        Dim output() As Byte = c.TransformFinalBlock(b, 0, b.Length)
        Return output
    End Function
End Class