# Visual Basic > Visual Basic .NET >  AES Encryption - length of data to decrypt invalid? Base64 conversion issues?

## BitFlipper88

Hi,

I am attempting to write my own AES encryption/decryption function. Its a dual purpose function and encrypts/decrypts based on a string prefix left padded in the cipher text.

When trying to decrypt back to plain text, the decryptor throws _Length of the data to decrypt is invalid._

On this line:  

```
Dim Result As String = Convert.ToBase64String(DECR.TransformFinalBlock(Buffer, 0, Buffer.Length))
```

I need another set of eyes on this. Because to me, it looks like my input is precisely the same as what is output as ciphertext in the encryptor branch.
Perhaps something is going on with Base64 conversion that I am missing. 

Thanks in advance for your time.

--------------------------------------------

IMPLEMENTATION:


```

        Dim SecretText As String = "My secret codes..."
        Dim CipherText As String

        CipherText = ENCRDECR(SecretText, "PasswordIsPassword")
        MsgBox("ENCR = " & CipherText)
        MsgBox("DECRYPT = " & ENCRDECR(CipherText, "PasswordIsPassword"))
```


CODE:


```
        Public Shared Function ENCRDECR(Input As String, Password As String) As String
            Dim AES As New RijndaelManaged
            Dim Hasher As New SHA256Managed
            Dim IV As String
            Dim IVBuffer As Byte()

            'DERIVE A LONGER 256 BIT PASS KEY FROM SHA256...
            Dim PassHashBuffer As Byte() = Hasher.ComputeHash(Text.Encoding.ASCII.GetBytes(Password))

            Dim EncrPrefix As String = "ENCR++/"  'Append to string, to identify whether input is plaintext or ciphertext

            Dim IVDelim As String = "#"  'IV in Encr operation left pads double equal. Hopefully this is more consistent?

            If Left(Input, Len(EncrPrefix)) = EncrPrefix Then  'INPUT IS CIPHER TEXT
                Debug.Print("RAW CIPHER: " & Input)
                'TEST FOR THE IV STRING, EXTRACT
                If Split(Input, IVDelim).Length <> 2 Then
                    Throw New System.Exception("Decryption Failed.")
                Else
                    Input = Right(Input, Len(Input) - Len(EncrPrefix)) 'strip encr prefix
                    IV = Split(Input, IVDelim)(0)  'acquire IV string
                    IVBuffer = Convert.FromBase64String(IV) 'convert to B64 buffer
                    Input = Right(Input, Len(Input) - Len(IV) - Len(IVDelim)) 'strip IV and delim to original encrypted cipher text

                    Debug.Print("RESOLVED CIPHER TEXT:" & Input)
                    'BUILD DECPYTOR
                    AES.Key = PassHashBuffer
                    AES.Mode = CipherMode.CBC
                    AES.IV = IVBuffer

                End If
                'DECRYPT
                Dim DECR As ICryptoTransform = AES.CreateDecryptor

                Dim Buffer As Byte() = Text.Encoding.ASCII.GetBytes(Input)
                Dim Result As String = Convert.ToBase64String(DECR.TransformFinalBlock(Buffer, 0, Buffer.Length))  ' **line that fails
                Result = Right(Result, Len(Result) - Len(EncrPrefix))
                DECR.Dispose()
                AES.Dispose()
                Return Result


            Else  'INPUT IS PLAIN TEXT - ENCRYPT
                AES.Key = PassHashBuffer
                AES.Mode = CipherMode.CBC
                AES.GenerateIV()  'sets the IV property to new generated

                IV = Convert.ToBase64String(AES.IV)
                Dim ENCR As ICryptoTransform = AES.CreateEncryptor
                Dim Buffer As Byte() = Text.Encoding.ASCII.GetBytes(Input)
                Dim Result As String = EncrPrefix & IV & "#" & Convert.ToBase64String(ENCR.TransformFinalBlock(Buffer, 0, Buffer.Length))
                Debug.Print("ENCRYPTED OUTPUT: " & Result)
                Debug.Print("GENERATED IV: " & IV)
                ENCR.Dispose()
                AES.Dispose()
                Return Result
            End If

        End Function
```



SEE ALSO:
https://stackoverflow.com/questions/...id-aes-c-sharp

https://stackoverflow.com/questions/...86740#14286740

----------


## BitFlipper88

Solved it.

Input on encryption side needed encoded to bytes from UTF8 - not ASCII.

Input on decryption side needed encoded "FromBase64String"

Then, final result in decryption is decoded to UTF8 string.


ENCRYPTION:


```
               Dim Buffer As Byte() = Text.Encoding.UTF8.GetBytes(Input)
                Dim Result As String = CipherPrefix & IV & "#" & Convert.ToBase64String(ENCR.TransformFinalBlock(Buffer, 0, Buffer.Length))
```


DECRYPTION:


```
                Dim Buffer As Byte() = Convert.FromBase64String(Input)
                Dim Result As String = Encoding.UTF8.GetString(DECR.TransformFinalBlock(Buffer, 0, Buffer.Length))
```

----------


## wqweto

You don't need to generate and encode IV -- just use fixed (zero) IV each time and be done with it.

Using a different one on each call does not strengthen security of your construction (provided that you transmit this IV in plain sight in the ciphertext) but only needlessly increase the size of encryped result, fiddle with delimiters and everything else.

Edit: If you do want to provide extra security by using a real IV in your construct then at this step

*Dim PassHashBuffer As Byte() = Hasher.ComputeHash(Text.Encoding.ASCII.GetBytes(Password))*
. . . you have to split this *PassHashBuffer* in two: first part will be used as a Key and the second part will be IV and on decryption you once again take the *Password* and produce both Key and IV from it so that you don't have to transmit the IV as plaintext.

Btw, instead of SHA256Managed for your hasher you can use some Rfc2898 based key-derivation function (so called PBKDF2) which from your short *Password* can produce a derived key of arbitrary length so that you have enough material/bytes for both Key and IV.

cheers,
</wqw>

----------

