Index out of range when decrypting a file

2.4k views Asked by At

I'm really not sure what's going on here. My app is encrypting files correctly and without issue, but it's throwing an IndexOutOfRangeException when trying to decrypt the same file...

Here's my code:

Public Sub EncryptDecrypt(ByVal Action As String, ByVal InFile As String, ByVal OutFile As String)
    Try
        Dim Buffer(4096) As Byte
        Dim Stream As CryptoStream
        Dim Rij As New System.Security.Cryptography.RijndaelManaged
        Dim Key(), IV() As Byte

        FSIn = New FileStream(InFile, FileMode.Open, FileAccess.Read)
        FSOut = New FileStream(OutFile, FileMode.OpenOrCreate, FileAccess.Write)
        FSOut.SetLength(0)

        Key = CreateKey("p0Ju423KQY7h4D29Ml536jbX7gS2Q6Rtm87XvRttlKiZ")
        IV = CreateIV("p0Ju423KQY7h4D29Ml536jbX7gS2Q6Rtm87XvRttlKiZ")

        If Action = "E" Then
            Stream = New CryptoStream(FSOut, Rij.CreateEncryptor(Key, IV), CryptoStreamMode.Write)
        Else
            Stream = New CryptoStream(FSOut, Rij.CreateDecryptor(Key, IV), CryptoStreamMode.Write)
        End If

        Stream.Close()
        FSIn.Close()
        FSOut.Close()
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

The error appears on the Stream.Close() line.
I have applied the same code elsewhere and it doesn't have any issues...

Here's my stack trace:

System.IndexOutOfRangeException was caught Message="Index was outside the bounds of the array."
Source="mscorlib" StackTrace: at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast) at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) at System.Security.Cryptography.CryptoStream.FlushFinalBlock() at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing) at System.IO.Stream.Close() at Crypt.EncryptDecrypt(String Action, String InFile, String OutFile) in D:\Development\Projects\Web\WebSite1\App_Code\Crypt.vb:line 34 InnerException:

Any help will be greatly appreciated.

EDIT 1 After aaz's comment, I revised and replaced

Stream = New CryptoStream(FSOut, Rij.CreateDecryptor(Key, IV), CryptoStreamMode.Write)

with

Stream = New CryptoStream(FSIn, Rij.CreateDecryptor(Key, IV), CryptoStreamMode.Write)

Here's the resulting Stack Trace:

System.IndexOutOfRangeException was caught Message="Index was outside the bounds of the array." Source="mscorlib" StackTrace: at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] > inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 > outputOffset, PaddingMode paddingMode, Boolean fLast) at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] > inputBuffer, Int32 inputOffset, Int32 inputCount) at System.Security.Cryptography.CryptoStream.FlushFinalBlock() at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing) at System.IO.Stream.Close() at Crypt.EncryptDecrypt(String Action, String InFile, String OutFile) in > D:\Development\Projects\Web\WebSite1\App_Code\Crypt.vb:line 34 InnerException:

Seems to me that its the same error...

END EDIT 1

2

There are 2 answers

1
Gent On BEST ANSWER

Well I think there are a couple things that need to be fixed. For one It does not appear that the FSOut is ever actually used now that you have changed the FSOut to FSIn. You seem to be using one or the other but from the structure of the code I would think your intent was to take a file In and encrypt or decrypt the data to another file.

Consider starting from scratch on this one using http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx as a jumping off point and if your intent is for it to read from one file and write to another modify it as you see fit or consider having a helper method that creates a copy of the file in memory, encrypts the file, moves it and replaces the in memory file to the starting location, doing it this way allows u to leverage this code for either case and doesn't really incur much extra overhead.

2
Jeffrey Hantin On

CryptoStream emits PKCS#7-style padding at the end of the data, which may include anywhere from one byte to one complete cipher block but is never zero-length; this ensures both that the encrypted stream is a multiple of the block size in length, and that padding can be unambiguously removed. Is it possible you are attempting to decrypt something that is not valid encrypted data?