0

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.'

   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
Jason
  • 1
  • 4
  • 2
    You probably need to decode the hex-encoded values to raw bytes, i.e. "FFFE" to {0xFF, 0xFE}. – Leśny Rumcajs Feb 25 '19 at 18:38
  • I thought that's what this does: Dim SharedKey As Byte() = Encoding.GetEncoding(1252).GetBytes(strSharedKey) strSharedKey is the hex value. I'm so lost lol – Jason Feb 25 '19 at 18:42
  • Why use 256-bit block size? That is not standardized as AES. Use AesCryptoServiceProvider – kelalaka Feb 25 '19 at 19:17
  • @Jason Your code does not decode hex; it just translates the characters into bytes. So "0A" becomes [48, 65], not 10. See https://stackoverflow.com/questions/10504034/how-do-you-convert-a-string-into-hexadecimal-in-vb-net – Rob Napier Feb 25 '19 at 19:36
  • ah. makes sense, I think. I have a function that will convert a string to a byte array. I used that in the Encrypt function and I get a return value but I have no idea if its correct. I posted the full code below as an answer for some reason – Jason Feb 25 '19 at 19:50

2 Answers2

0

For CBC mode (and most other modes) the IV length must be the same as the block length. By default with the .NET CLR RijndaelManaged cipher, the block length is 128 bits (16 bytes). You can set this with

aes.BlockSize = 256

Which would allow a 32 byte IV, but also use blocks of 32 bytes.

Also, your comments suggest that you are using a 64 byte (512 bit) key. That should be a 32 byte (256 bit) key.

Paul Reeder
  • 139
  • 6
  • If I set the aes.BlockSize = 256, I get the same error BUT I did get it to compile and return a value where the last 2 characters are "==" by adding SharedKey = StringToByteArray(strSharedKey) – Jason Feb 25 '19 at 19:22
0

These are what I used. Whether or not the returned value is correct, I have no idea yet.

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

Any other ideas would be very helpful

Jason
  • 1
  • 4