Search code examples
vb.netencryptionaes

Standard library for AES encryption for VB.NET?


Is there a standard library to use for AES encryption for VB.NET? I want to encrypt a string with a static private key.

I googled and found a lot of variations. I don't really know how to determine which algorithms are secure or not.


Solution

  • The System.Security.Cryptography namespace contains all the classes you need to perform most standard encryption tasks. Unfortunately, since encryption is a rather complicated topic, the classes are somewhat difficult to work with--especially for beginners. It's sometimes difficult to find a simple working example to start with. But, since I'm nice, I'll provide you with a simple example that you can play with and improve upon :)

    The class you probably want to use is called RijndaelManaged. That is the class that implements the typical AES encryption. Here's a sample class that uses that to convert between plain text strings and byte arrays:

    Public Class Aes256Encrypter
        Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As Byte()
            Dim encryptedPassword As Byte()
            Using outputStream As MemoryStream = New MemoryStream()
                Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
                Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write)
                    Dim inputBuffer() As Byte = Encoding.Unicode.GetBytes(plainText)
                    cryptoStream.Write(inputBuffer, 0, inputBuffer.Length)
                    cryptoStream.FlushFinalBlock()
                    encryptedPassword = outputStream.ToArray()
                End Using
            End Using
            Return encryptedPassword
        End Function
    
        Public Function Decrypt(ByVal encryptedBytes As Byte(), ByVal secretKey As String) As String
            Dim plainText As String = Nothing
            Using inputStream As MemoryStream = New MemoryStream(encryptedBytes)
                Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
                Using cryptoStream As CryptoStream = New CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read)
                    Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte
                    Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer))
                    plainText = Encoding.Unicode.GetString(outputBuffer, 0, readBytes)
                End Using
            End Using
            Return plainText
        End Function
    
        Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged
            Const salt As String = "put your salt here"
            Const keySize As Integer = 256
    
            Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Encoding.Unicode.GetBytes(salt))
            Dim algorithm As RijndaelManaged = New RijndaelManaged()
            algorithm.KeySize = keySize
            algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize / 8, Integer))
            algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize / 8, Integer))
            algorithm.Padding = PaddingMode.PKCS7
            Return algorithm
        End Function
    End Class
    

    You should change the salt constant to something else. Ideally, it wouldn't even be a constant, since, to make it as secure as possible, you should use a different salt each time you perform the encryption, but that's a whole other topic.

    If you want to have the encrypted value returned as a string instead of as a byte array, you can use Base-64 encoding to convert the byte array to, and from, strings, like this:

    Public Class Aes256Base64Encrypter
        Public Function Encrypt(ByVal plainText As String, ByVal secretKey As String) As String
            Dim encryptedPassword As String = Nothing
            Using outputStream As MemoryStream = New MemoryStream()
                Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
                Using cryptoStream As CryptoStream = New CryptoStream(outputStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write)
                    Dim inputBuffer() As Byte = Encoding.Unicode.GetBytes(plainText)
                    cryptoStream.Write(inputBuffer, 0, inputBuffer.Length)
                    cryptoStream.FlushFinalBlock()
                    encryptedPassword = Convert.ToBase64String(outputStream.ToArray())
                End Using
            End Using
            Return encryptedPassword
        End Function
    
        Public Function Decrypt(ByVal encryptedBytes As String, ByVal secretKey As String) As String
            Dim plainText As String = Nothing
            Using inputStream As MemoryStream = New MemoryStream(Convert.FromBase64String(encryptedBytes))
                Dim algorithm As RijndaelManaged = getAlgorithm(secretKey)
                Using cryptoStream As CryptoStream = New CryptoStream(inputStream, algorithm.CreateDecryptor(), CryptoStreamMode.Read)
                    Dim outputBuffer(0 To CType(inputStream.Length - 1, Integer)) As Byte
                    Dim readBytes As Integer = cryptoStream.Read(outputBuffer, 0, CType(inputStream.Length, Integer))
                    plainText = Encoding.Unicode.GetString(outputBuffer, 0, readBytes)
                End Using
            End Using
            Return plainText
        End Function
    
        Private Function getAlgorithm(ByVal secretKey As String) As RijndaelManaged
            Const salt As String = "put your salt here"
            Const keySize As Integer = 256
    
            Dim keyBuilder As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(secretKey, Encoding.Unicode.GetBytes(salt))
            Dim algorithm As RijndaelManaged = New RijndaelManaged()
            algorithm.KeySize = keySize
            algorithm.IV = keyBuilder.GetBytes(CType(algorithm.BlockSize / 8, Integer))
            algorithm.Key = keyBuilder.GetBytes(CType(algorithm.KeySize / 8, Integer))
            algorithm.Padding = PaddingMode.PKCS7
            Return algorithm
        End Function
    End Class
    

    If you are storing the encrypted value in a text file, XML file, or even a database, it's often easier to just use Base-64, like that.