AES Encryption of a string

ahbenshaut

Well-known member
Joined
Oct 29, 2004
Messages
62
Location
Alaska
Programming Experience
5-10
greetings. I am trying to encrypt a string using the code below. The issue is I get this error and I have no clue (I'm just learning about encryption) what to do or even where to look. The SharedKey and the IV have been supplied as Hex values. The SharedKey is 64 bytes and the IV is 32 bytes.

System.Security.Cryptography.CryptographicException: 'Specified initialization vector (IV) does not match the block size for this algorithm.'

VB.NET:
    Public Function Encrypt(ByVal strValue As String) As String
        'Create instance of a Rijndael Managed object
        Dim aes As New RijndaelManaged
        'Set appropriate values of object
        aes.Padding = PaddingMode.PKCS7
        aes.KeySize = 256
        aes.Mode = CipherMode.CBC
        'Create streams to work with encryption process
        Dim msEncrypt As New MemoryStream()
        'SharedKey = "64 byte string"
        'IV = "32 byte string"
        Dim SharedKey As Byte() = Encoding.GetEncoding(1252).GetBytes(strSharedKey)
        Dim IV As Byte() = Encoding.GetEncoding(1252).GetBytes(strIV)
        Dim csEncrypt As New CryptoStream(msEncrypt, aes.CreateEncryptor(SharedKey, IV), CryptoStreamMode.Write)
        'Convert string value to byte array
        Dim toEncrypt As Byte() = Encoding.GetEncoding(1252).GetBytes(strValue)
        toEncrypt = Encoding.Convert(Encoding.GetEncoding(1252), Encoding.UTF8, toEncrypt)
        'Perform encryption
        csEncrypt.Write(toEncrypt, 0, toEncrypt.Length)
        csEncrypt.FlushFinalBlock()
        'Return Base64 string
        Return Convert.ToBase64String(msEncrypt.ToArray())
        'Dim u As System.Text.UnicodeEncoding = System.Text.Encoding.Unicode
        'Dim a As System.Text.ASCIIEncoding = System.Text.Encoding.ASCII
        'Return a.GetByteCount(SharedKey)  '64 bytes
    End Function

Any help is mucho appreciated
 
Look at .LegalBlockSizes/.LegalKeySizes, they are 128-256 bits which is 16-32 bytes. IV is usually equal to block size, default 16 bytes, but can be upped to 32 bytes it looks like.
 
Last edited:
Well, I was able to get it to compile but I have no idea if the returned value is correct. this is what I did:

VB.NET:
    Public Function Encrypt(ByVal strValue As String) As String
        'Create instance of a Rijndael Managed object
        Dim aes As New RijndaelManaged
        'Set appropriate values of object
        aes.Padding = PaddingMode.PKCS7
        aes.KeySize = 256
        aes.Mode = CipherMode.CBC
        'Create streams to work with encryption process
        Dim msEncrypt As New MemoryStream()
        Dim SharedKey As Byte()
        'SharedKey = ""
        'IV = ""
        SharedKey = StringToByteArray(strSharedKey)
        Dim IV As Byte()
        IV = StringToByteArray(strIV)

        Dim csEncrypt As New CryptoStream(msEncrypt, aes.CreateEncryptor(SharedKey, IV), CryptoStreamMode.Write)
        'Convert string value to byte array
        Dim toEncrypt As Byte() = Encoding.GetEncoding(1252).GetBytes(strValue)
        toEncrypt = Encoding.Convert(Encoding.GetEncoding(1252), Encoding.UTF8, toEncrypt)
        'Perform encryption
        csEncrypt.Write(toEncrypt, 0, toEncrypt.Length)
        csEncrypt.FlushFinalBlock()
        'Return Base64 string
        Return Convert.ToBase64String(msEncrypt.ToArray())
    End Function

    Function StringToByteArray(text As String) As Byte()
        Dim bytes As Byte() = New Byte(text.Length \ 2 - 1) {}
        For i As Integer = 0 To text.Length - 1 Step 2
            bytes(i \ 2) = Byte.Parse(text(i).ToString() & text(i + 1).ToString(), System.Globalization.NumberStyles.HexNumber)
        Next
        Return bytes
    End Function
 
It makes sense that the hex string is two hex digits per char (it can also be one) so you initially got twice key/IV the length.
You can also use this in your loop (16 is the number system base for hex):
VB.NET:
bytes(i / 2) = Convert.ToByte(text.Substring(i, 2), 16)
 
Last edited:
I have posted this code previously, but here it is again with the nice new code formatting... The following will encrypt strings using AES-256 and encode the result to base64, and also take a base64 string, decode it and decrypt it. This uses a unique salt every encryption (a random GUID), and the salt is prepended to the encrypted cipher text before encoding to base64. The decryption routine decodes to a byte array, and uses the salt and key to decrypt the ciphertext.

VB.NET:
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim MyPlainTextMessage As String = "Station 1 " & DateTime.Now.ToString()
        Dim MyKey As String = "00000000000000000000000000000000"

        Dim EncryptedCipherText As String = AESEncryptStringToBase64(MyPlainTextMessage, MyKey)

        Dim DecryptedPlainText As String = AESDecryptBase64ToString(EncryptedCipherText, MyKey)

        MessageBox.Show("Plain text: " & MyPlainTextMessage & vbCrLf & _
                        "Encrypted Base64 cipher: " & EncryptedCipherText & vbCrLf & _
                        "Decrypted plain text: " & DecryptedPlainText)
    End Sub

    Private Function AESEncryptStringToBase64(strPlainText As String, strKey As String) As String
        Dim Algo As RijndaelManaged = RijndaelManaged.Create()

        With Algo
            .BlockSize = 128
            .FeedbackSize = 128
            .KeySize = 256
            .Mode = CipherMode.CBC
            .IV = Guid.NewGuid().ToByteArray()
            .Key = Encoding.ASCII.GetBytes(strKey)
        End With


        Using Encryptor As ICryptoTransform = Algo.CreateEncryptor()
            Using MemStream As New MemoryStream
                Using CryptStream As New CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write)
                    Using Writer As New StreamWriter(CryptStream)
                        Writer.Write(strPlainText)
                    End Using

                    AESEncryptStringToBase64 = Convert.ToBase64String(Algo.IV.Concat(MemStream.ToArray()).ToArray())
                End Using
            End Using
        End Using
    End Function

    Private Function AESDecryptBase64ToString(strCipherText As String, strKey As String) As String
        Dim arrSaltAndCipherText As Byte() = Convert.FromBase64String(strCipherText)

        Dim Algo As RijndaelManaged = RijndaelManaged.Create()

        With Algo
            .BlockSize = 128
            .FeedbackSize = 128
            .KeySize = 256
            .Mode = CipherMode.CBC
            .IV = arrSaltAndCipherText.Take(16).ToArray()
            .Key = Encoding.ASCII.GetBytes(strKey)
        End With


        Using Decryptor As ICryptoTransform = Algo.CreateDecryptor()
            Using MemStream As New MemoryStream(arrSaltAndCipherText.Skip(16).ToArray())
                Using CryptStream As New CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)
                    Using Reader As New StreamReader(CryptStream)
                        AESDecryptBase64ToString = Reader.ReadToEnd()
                    End Using
                End Using
            End Using
        End Using
    End Function

End Class
 
Last edited:
I have posted this code previously, but here it is again with the nice new code formatting... The following will encrypt strings using AES-256 and encode the result to base64, and also take a base64 string, decode it and decrypt it. This uses a unique salt every encryption (a random GUID), and the salt is prepended to the encrypted cipher text before encoding to base64. The decryption routine decodes to a byte array, and uses the salt and key to decrypt the ciphertext.

VB.NET:
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim MyPlainTextMessage As String = "Station 1 " & DateTime.Now.ToString()
        Dim MyKey As String = "00000000000000000000000000000000"

        Dim EncryptedCipherText As String = AESEncryptStringToBase64(MyPlainTextMessage, MyKey)

        Dim DecryptedPlainText As String = AESDecryptBase64ToString(EncryptedCipherText, MyKey)

        MessageBox.Show("Plain text: " & MyPlainTextMessage & vbCrLf & _
                        "Encrypted Base64 cipher: " & EncryptedCipherText & vbCrLf & _
                        "Decrypted plain text: " & DecryptedPlainText)
    End Sub

    Private Function AESEncryptStringToBase64(strPlainText As String, strKey As String) As String
        Dim Algo As RijndaelManaged = RijndaelManaged.Create()

        With Algo
            .BlockSize = 128
            .FeedbackSize = 128
            .KeySize = 256
            .Mode = CipherMode.CBC
            .IV = Guid.NewGuid().ToByteArray()
            .Key = Encoding.ASCII.GetBytes(strKey)
        End With


        Using Encryptor As ICryptoTransform = Algo.CreateEncryptor()
            Using MemStream As New MemoryStream
                Using CryptStream As New CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write)
                    Using Writer As New StreamWriter(CryptStream)
                        Writer.Write(strPlainText)
                    End Using

                    AESEncryptStringToBase64 = Convert.ToBase64String(Algo.IV.Concat(MemStream.ToArray()).ToArray())
                End Using
            End Using
        End Using
    End Function

    Private Function AESDecryptBase64ToString(strCipherText As String, strKey As String) As String
        Dim arrSaltAndCipherText As Byte() = Convert.FromBase64String(strCipherText)

        Dim Algo As RijndaelManaged = RijndaelManaged.Create()

        With Algo
            .BlockSize = 128
            .FeedbackSize = 128
            .KeySize = 256
            .Mode = CipherMode.CBC
            .IV = arrSaltAndCipherText.Take(16).ToArray()
            .Key = Encoding.ASCII.GetBytes(strKey)
        End With


        Using Decryptor As ICryptoTransform = Algo.CreateDecryptor()
            Using MemStream As New MemoryStream(arrSaltAndCipherText.Skip(16).ToArray())
                Using CryptStream As New CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)
                    Using Reader As New StreamReader(CryptStream)
                        AESDecryptBase64ToString = Reader.ReadToEnd()
                    End Using
                End Using
            End Using
        End Using
    End Function

End Class

I registered on this forum just to say a massive thanks for publishing your code! I tried using a static IV that the user enters each time, rather than one that changes and it worked how I wanted it to as in creating the same Base64 string each time. But then, I was curious what the Base64 decoded to without any AES decryption and used an online Base64 decoder. Well, that displayed the IV in plaintext at the start of the message! So I decide to stuff that idea and went back to your original coding!
 
I have posted this code previously, but here it is again with the nice new code formatting... The following will encrypt strings using AES-256 and encode the result to base64, and also take a base64 string, decode it and decrypt it. This uses a unique salt every encryption (a random GUID), and the salt is prepended to the encrypted cipher text before encoding to base64. The decryption routine decodes to a byte array, and uses the salt and key to decrypt the ciphertext.

VB.NET:
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim MyPlainTextMessage As String = "Station 1 " & DateTime.Now.ToString()
        Dim MyKey As String = "00000000000000000000000000000000"

        Dim EncryptedCipherText As String = AESEncryptStringToBase64(MyPlainTextMessage, MyKey)

        Dim DecryptedPlainText As String = AESDecryptBase64ToString(EncryptedCipherText, MyKey)

        MessageBox.Show("Plain text: " & MyPlainTextMessage & vbCrLf & _
                        "Encrypted Base64 cipher: " & EncryptedCipherText & vbCrLf & _
                        "Decrypted plain text: " & DecryptedPlainText)
    End Sub

    Private Function AESEncryptStringToBase64(strPlainText As String, strKey As String) As String
        Dim Algo As RijndaelManaged = RijndaelManaged.Create()

        With Algo
            .BlockSize = 128
            .FeedbackSize = 128
            .KeySize = 256
            .Mode = CipherMode.CBC
            .IV = Guid.NewGuid().ToByteArray()
            .Key = Encoding.ASCII.GetBytes(strKey)
        End With


        Using Encryptor As ICryptoTransform = Algo.CreateEncryptor()
            Using MemStream As New MemoryStream
                Using CryptStream As New CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write)
                    Using Writer As New StreamWriter(CryptStream)
                        Writer.Write(strPlainText)
                    End Using

                    AESEncryptStringToBase64 = Convert.ToBase64String(Algo.IV.Concat(MemStream.ToArray()).ToArray())
                End Using
            End Using
        End Using
    End Function

    Private Function AESDecryptBase64ToString(strCipherText As String, strKey As String) As String
        Dim arrSaltAndCipherText As Byte() = Convert.FromBase64String(strCipherText)

        Dim Algo As RijndaelManaged = RijndaelManaged.Create()

        With Algo
            .BlockSize = 128
            .FeedbackSize = 128
            .KeySize = 256
            .Mode = CipherMode.CBC
            .IV = arrSaltAndCipherText.Take(16).ToArray()
            .Key = Encoding.ASCII.GetBytes(strKey)
        End With


        Using Decryptor As ICryptoTransform = Algo.CreateDecryptor()
            Using MemStream As New MemoryStream(arrSaltAndCipherText.Skip(16).ToArray())
                Using CryptStream As New CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read)
                    Using Reader As New StreamReader(CryptStream)
                        AESDecryptBase64ToString = Reader.ReadToEnd()
                    End Using
                End Using
            End Using
        End Using
    End Function

End Class

Hello could you tell me how I can use this function?
I have input decrypted .TS Files and also key file.
And I want to have single output of ts file
 
The AESEncryptStringToBase64 method accepts the text to be encrypted and returns the encrypted data as text in base-64 format. If you have a file then you can call File.ReadAllText to get the plain text. What you do with the encrypted text is up to you, e.g. call File.WriteAllText to write it to a file. The AESDecryptBase64ToString method goes the other way, i.e. you pass it base-64 text that was encrypted this way and it will pass you back the original plain text. That's it, that's all.
 
The AESEncryptStringToBase64 method accepts the text to be encrypted and returns the encrypted data as text in base-64 format. If you have a file then you can call File.ReadAllText to get the plain text. What you do with the encrypted text is up to you, e.g. call File.WriteAllText to write it to a file. The AESDecryptBase64ToString method goes the other way, i.e. you pass it base-64 text that was encrypted this way and it will pass you back the original plain text. That's it, that's all.

Alright. thank you I'm gonna try it tomorrow.

Admin could you please evaluate my codes if I'm doing wrong or nothing.
Here's the progress of my fixing some problem with the memory usage and processing takes long.
I also put some of your suggested codes and format.

VB.NET:
 Private Sub BGW_DoWork(sender As Object, e As DoWorkEventArgs) Handles BGW.DoWork
        Dim newWorer As BackgroundWorker = DirectCast(sender, BackgroundWorker)

        Dim inputFolderPath = txtInputFolder.Text
        Dim outputFolderPath = txtOutputFolder.Text
        Dim outputFilePath = Path.Combine(outputFolderPath, txtOutputFileName.Text & ".ts")
        Dim inputFilePath = Directory.GetFiles(inputFolderPath, "*.ts")

        Dim IV(15) As Byte
        Dim key As Byte() = File.ReadAllBytes(txtKeyPath.Text)
        Dim Algo As AesManaged = New AesManaged

        Try
            Using outputStream = File.Create(outputFilePath)
                For i As Integer = 0 To inputFilePath.Length - 1 'COUNT FILES
                    Using inputStream = File.OpenRead(inputFilePath(i))

                        With Algo
                            Algo.BlockSize = 128
                            Algo.KeySize = 128
                            Algo.Key = key
                            Algo.IV = IV
                            Algo.Mode = CipherMode.CBC
                            Algo.Padding = PaddingMode.PKCS7
                        End With

                        Using AESDecrypter As ICryptoTransform = Algo.CreateDecryptor
                            Using cryptoStream As CryptoStream = New CryptoStream(inputStream, AESDecrypter, CryptoStreamMode.Read)

                                While inputStream.Position < inputFilePath.Length

                                    cryptoStream.CopyTo(outputStream) 'PROCESSING

                                    newWorer.ReportProgress(i / inputFilePath.Length * 100) 'REPORT PROGRESS

                                    If BGW.CancellationPending = True Then
                                        e.Cancel = True
                                        Exit For
                                    End If

                                End While
                            End Using
                        End Using
                    End Using
                Next
            End Using
        Catch ex As Exception
        End Try
    End Sub
 
This will encrypt anything with 256 -bit encryption, make sure the password for the encryption matches the decryption. Not a billion computers with the technology we have could crack it. It would take thousands of years. See the bottom for my YouTube channel with tutorials on this and lot's of other stuff:

Using: Visual Studios Community Edition 2019
Items Needed:
*3 buttons "Browse File", "Encrypt File", "Decrypt File"
*1 textbox

Here's the tutorial:


VB.NET:
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text

Public Class Precursor


    Public Function Rijndael_Encrypt(bytesToBeEncrypted As Byte(), passwordBytes As Byte()) As Byte()

        Dim Rythorian77 As String = TextBox1.Text

        Dim pass As String = "123456789ABCDEFG!@#$%^&*()_+"

        Dim key As Byte() = New Byte(31) {}

        'When overridden in a derived class, encodes a set of characters into a sequence of bytes.
        Encoding.Default.GetBytes(pass).CopyTo(key, 0)

        ' Encoding.Default.GetBytes(pass).CopyTo(saltBytes, 0)
        Using ms As New MemoryStream

            Using AES As New RijndaelManaged()
                AES.KeySize = 256
                AES.BlockSize = 256
                Dim kay = New Rfc2898DeriveBytes(passwordBytes, key, 1000)
                AES.Key = kay.GetBytes(AES.KeySize / 8)
                AES.IV = kay.GetBytes(AES.BlockSize / 8)
                AES.Mode = CipherMode.CBC

                Using cs = New CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)
                    cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length)
                    cs.Close()
                End Using

                key = ms.ToArray()
            End Using
        End Using

        Return key
    End Function

    Public Function Rijndael_Decrypt(bytesToBeDecrypted As Byte(), passwordBytes As Byte()) As Byte()

        Dim Rythorian77 As String = TextBox1.Text

        Dim pass As String = "123456789ABCDEFG!@#$%^&*()_+"

        Dim key As Byte() = New Byte(31) {}

        'When overridden in a derived class, encodes a set of characters into a sequence of bytes.
        Encoding.Default.GetBytes(pass).CopyTo(key, 0)

        ' Encoding.Default.GetBytes(pass).CopyTo(saltBytes, 0)
        Using ms As New MemoryStream

            Using AES As New RijndaelManaged()
                AES.KeySize = 256
                AES.BlockSize = 256
                Dim kay = New Rfc2898DeriveBytes(passwordBytes, key, 1000)
                AES.Key = kay.GetBytes(AES.KeySize / 8)
                AES.IV = kay.GetBytes(AES.BlockSize / 8)
                AES.Mode = CipherMode.CBC

                Using cs = New CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write)
                    cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length)
                    cs.Close()
                End Using

                key = ms.ToArray()
            End Using
        End Using

        Return key
    End Function

    Private Sub AESEncrypt_Click(sender As Object, e As EventArgs) Handles AESEncrypt.Click

        Dim file As String = TextBox1.Text

        Dim pass As String = ""

        Dim bytesToBeEncrypted As Byte() = IO.File.ReadAllBytes(file)

        Dim passwordBytes As Byte() = Encoding.UTF8.GetBytes(pass)

        passwordBytes = SHA256.Create().ComputeHash(passwordBytes)

        Dim bytesEncrypted As Byte() = Rijndael_Encrypt(bytesToBeEncrypted, passwordBytes)

        IO.File.WriteAllBytes(file, bytesEncrypted)

        IO.File.Move(file, file & ".Rythorian")

    End Sub

    Private Sub FileBrowse_Click(sender As Object, e As EventArgs) Handles FileBrowse.Click
        'Allows you to access files from folders
        Dim CryptDialog As New OpenFileDialog With {
            .CheckFileExists = True,
            .InitialDirectory = "C:\",
            .Multiselect = False
        }

        If CryptDialog.ShowDialog = DialogResult.OK Then
            TextBox1.Text = CryptDialog.FileName
        End If
    End Sub

    Private Sub AESDecrypt_Click(sender As Object, e As EventArgs) Handles AESDecrypt.Click

        Dim file As String = TextBox1.Text

        Dim pass As String = ""
        Try
            Dim bytesToBeDecrypted As Byte() = IO.File.ReadAllBytes(file)

            Dim passwordBytes As Byte() = Encoding.UTF8.GetBytes(pass)

            passwordBytes = SHA256.Create().ComputeHash(passwordBytes)

            Dim bytesDecrypted As Byte() = Rijndael_Decrypt(bytesToBeDecrypted, passwordBytes)

            IO.File.WriteAllBytes(file, bytesDecrypted)

            Dim extension As String = Path.GetExtension(file)

            Dim result As String = file.Substring(0, file.Length - extension.Length)

            IO.File.Move(file, result)

        Catch ex As Exception
            MsgBox(ex.ToString())
        End Try


    End Sub
End Class


YouTube Tutorial:
 
Last edited by a moderator:
Back
Top