Link to home
Start Free TrialLog in
Avatar of sk33v3
sk33v3

asked on

length of data to decrypt is invalid

I am getting the following error when I try to decrypt a string.

"length of data to decrypt is invalid"

How can i fix this? The information that is being passed is all the information that was encrypted. Do I need to add padding when encrypting?
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Can you show us your encrypting/decrypting code?...
Avatar of sk33v3
sk33v3

ASKER

Here is the dummy form that I am using to run some testing with

Imports System.Security.Cryptography
Public Class Form1
    Dim Key() As Byte
    Dim IV() As Byte

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim Buffer(0 To 1000) As Byte
        Dim CryptAlg As SymmetricAlgorithm = SymmetricAlgorithm.Create("Rijndael")
        Dim CSTE As ICryptoTransform
        Dim Base64 As New ToBase64Transform
        Dim Base64Output As New ToBase64Transform
        Dim FS As New IO.FileStream("C:\primes.log", IO.FileMode.Open)
        Dim Stream64 As New CryptoStream(FS, Base64, CryptoStreamMode.Read)
        Dim Output64 As CryptoStream
        Dim CS As CryptoStream

        CryptAlg.GenerateKey()
        CryptAlg.GenerateIV()
        Key = CryptAlg.Key
        IV = CryptAlg.IV
        CryptAlg.Padding = PaddingMode.Zeros
        CSTE = CryptAlg.CreateEncryptor
        CS = New CryptoStream(Stream64, CSTE, CryptoStreamMode.Read)
        output64 = New CryptoStream(CS, base64output, CryptoStreamMode.Read)
        Output64.Read(Buffer, 0, Buffer.Length)
        Do Until Len(Trim(System.Text.Encoding.Default.GetString(Buffer))) < 1
            Me.TextBox1.AppendText(System.Text.Encoding.Default.GetString(Buffer)) ''CStr(Buffer)
            Buffer = System.Text.Encoding.Default.GetBytes(StrDup(1001, " "))
            Output64.Read(Buffer, 0, Buffer.Length)

        Loop
        Decrypt()
    End Sub

    Private Sub Decrypt()
        Dim Buffer(0 To 1000) As Byte
        Dim CryptAlg As SymmetricAlgorithm = SymmetricAlgorithm.Create("Rijndael")
        Dim CSTE As ICryptoTransform
        Dim Base64 As New FromBase64Transform
        Dim Base64Output As New FromBase64Transform
        Dim FS As New IO.MemoryStream(System.Text.Encoding.Default.GetBytes(Me.TextBox1.Text), 0, Me.TextBox1.Text.Length)
        Dim Stream64 As New CryptoStream(FS, Base64, CryptoStreamMode.Read)
        Dim Output64 As CryptoStream
        Dim CS As CryptoStream
        Me.TextBox1.AppendText(vbCrLf & vbCrLf & vbCrLf)

        CryptAlg.Key = Key
        CryptAlg.IV = IV
        CryptAlg.Padding = PaddingMode.Zeros
        CSTE = CryptAlg.CreateDecryptor
        CS = New CryptoStream(Stream64, CSTE, CryptoStreamMode.Read)
        Output64 = New CryptoStream(CS, Base64Output, CryptoStreamMode.Read)
        Output64.Read(Buffer, 0, Buffer.Length)
        Do Until Len(Trim(System.Text.Encoding.Default.GetString(Buffer))) < 1
            Me.TextBox1.AppendText(System.Text.Encoding.Default.GetString(Buffer)) ''CStr(Buffer)
            Buffer = System.Text.Encoding.Default.GetBytes(StrDup(1001, " "))
            Output64.Read(Buffer, 0, Buffer.Length)

        Loop
    End Sub
End Class

Just drop a textbox and make it multiline...
Avatar of sk33v3

ASKER

ok I fixed my own problem. So let me go into a little detail as to what I did to solve the problem. First since the data being encrypted might contain a null character I couldn't just encrypt and decrypt and cut the encrypted text off at the first null I saw or for that matter any null character. Which is where I was getting the length of data to decrypt is invalid. That error was coming up because no padding was being added. Once I added the padding of null characters it decrypted with a few null characters at the end which of course would end up corrupting the file. Ah ha a light bulb fired off and i figured I would base 64 encode the text before I encrypted it because base 64 encoding did not contain null characters I figured I would base 64 encode and then encrypt. Now if you look at the above you will notice there is a second base 64 encoding going on after the encryption. That is because the data needed to be base 64 encoded after the encryption for misc reason that could cause errors if I didn't. So back to the problem I had with the code above. During the decryption routine I would get invalid character in base64 string. Ack! the null padding is biting me in the butt. What I finally ended up doing is the decryption routine write the data to a temporary Stream. In my case I decided to use a temp file because the data could get very large(a few gigs sometimes). No the decryption routine now take the data and base64 decodes then does the decryption, all in one step, and then writes it to the temporary memory stream. Before writing the data to the temporary memory stream I replace all chr(0)'s with chr(32)'s, a space. once the data is completely decrypted I run a second loop that does the final base64 decoding and poof the data is back to normal and all is working. I plan on posting up some code here in a bit of exactly what I did so others can learn from my headaches.
Lol...glad you figured it out.  =)

I hadn't gotten around to playing with your code yet....
Avatar of sk33v3

ASKER

So much work for something that seems so simple.
Avatar of sk33v3

ASKER

ok here is the final test application that I used to test things out. So note this is not optimized and may even contain things that could be removed.

Imports System.Security.Cryptography
Public Class Form1
    Dim Key() As Byte
    Dim IV() As Byte

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim Buffer(0 To 1000) As Byte
        Dim CryptAlg As SymmetricAlgorithm = SymmetricAlgorithm.Create("Rijndael")
        Dim CSTE As ICryptoTransform
        Dim Base64 As New ToBase64Transform
        Dim Base64Output As New ToBase64Transform
        Dim FS As New IO.FileStream("C:\primes.log", IO.FileMode.Open)
        Dim Stream64 As New CryptoStream(FS, Base64, CryptoStreamMode.Read)
        Dim Output64 As CryptoStream
        Dim CS As CryptoStream

        CryptAlg.GenerateKey()
        CryptAlg.GenerateIV()
        Key = CryptAlg.Key
        IV = CryptAlg.IV
        CryptAlg.Padding = PaddingMode.Zeros
        CSTE = CryptAlg.CreateEncryptor
        CS = New CryptoStream(Stream64, CSTE, CryptoStreamMode.Read)
        output64 = New CryptoStream(CS, base64output, CryptoStreamMode.Read)
        Output64.Read(Buffer, 0, Buffer.Length)
        Do Until Len(Trim(System.Text.Encoding.Default.GetString(Buffer))) < 1
            Me.TextBox1.AppendText(System.Text.Encoding.Default.GetString(Buffer)) ''CStr(Buffer)
            Buffer = System.Text.Encoding.Default.GetBytes(StrDup(1001, " "))
            Output64.Read(Buffer, 0, Buffer.Length)

        Loop
        Decrypt()
    End Sub

    Private Sub Decrypt()
        Dim Buffer(0 To 1000) As Byte
        Dim CryptAlg As SymmetricAlgorithm = SymmetricAlgorithm.Create("Rijndael")
        Dim CSTE As ICryptoTransform
        Dim Base64 As New FromBase64Transform
        Dim Base64Output As New FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces)
        Dim MS As New IO.MemoryStream(System.Text.Encoding.Default.GetBytes(Me.TextBox1.Text), 0, Me.TextBox1.Text.Length)
        Dim Stream64 As New CryptoStream(MS, Base64, CryptoStreamMode.Read)
        Dim Output64 As CryptoStream
        Dim CS As CryptoStream
        Dim IntX As Integer
        Dim StrTmp As String
        Dim FS As New IO.FileStream(My.Application.Info.DirectoryPath & "\tmp.decode", IO.FileMode.OpenOrCreate, IO.FileAccess.Write)
        Me.TextBox1.AppendText(vbCrLf & vbCrLf & vbCrLf)

        CryptAlg.Key = Key
        CryptAlg.IV = IV
        CryptAlg.Padding = PaddingMode.Zeros
        CSTE = CryptAlg.CreateDecryptor
        CS = New CryptoStream(Stream64, CSTE, CryptoStreamMode.Read)
        IntX = CS.Read(Buffer, 0, Buffer.Length)
        Do Until Len(Trim(System.Text.Encoding.Default.GetString(Buffer))) < 1
            StrTmp = System.Text.Encoding.Default.GetString(Buffer)
            If InStr(StrTmp, "=") Then
                StrTmp = StrTmp.Replace(Chr(0), Chr(32))
                IntX = Len(Trim(StrTmp))
                FS.Write(System.Text.Encoding.Default.GetBytes(StrTmp), 0, Len(StrTmp))
                Exit Do
            Else
                IntX = Buffer.Length
            End If
            FS.Write(Buffer, 0, IntX)
            Buffer = System.Text.Encoding.Default.GetBytes(StrDup(1001, " "))
            IntX = CS.Read(Buffer, 0, Buffer.Length)

        Loop
        FS.Close()
        FS = New IO.FileStream(My.Application.Info.DirectoryPath & "\tmp.decode", IO.FileMode.Open, IO.FileAccess.Read)

        Output64 = New CryptoStream(FS, Base64Output, CryptoStreamMode.Read)
        Output64.Read(Buffer, 0, Buffer.Length)
        Do Until Len(Trim(System.Text.Encoding.Default.GetString(Buffer))) < 1
            If IntX < Buffer.Length Then
                MsgBox(IntX)
            End If
            Me.TextBox1.AppendText(System.Text.Encoding.Default.GetString(Buffer).Substring(0, IntX)) ''CStr(Buffer)
            Buffer = System.Text.Encoding.Default.GetBytes(StrDup(1001, " "))
            IntX = Output64.Read(Buffer, 0, IntX)
        Loop

    End Sub
End Class
ASKER CERTIFIED SOLUTION
Avatar of modulo
modulo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial