解密文件时出现索引超出范围的错误

6

我真的不确定这里发生了什么。我的应用程序可以正确地加密文件,没有问题,但是尝试解密相同的文件时,它会抛出IndexOutOfRangeException异常...

这是我的代码:

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

错误出现在Stream.Close()行。
我已经在其他地方应用了相同的代码,没有任何问题...
以下是我的堆栈跟踪:

System.IndexOutOfRangeException被捕获 Message="索引超出了数组界限。"
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:

任何帮助将不胜感激。
编辑1:在aaz的评论后,我进行了修订和替换。
Stream = New CryptoStream(FSOut, Rij.CreateDecryptor(Key, IV), CryptoStreamMode.Write)

使用

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

以下是产生的堆栈跟踪:

捕获到 System.IndexOutOfRangeException 异常 Message="索引超出了数组界限。" 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:

对我来说,这似乎是同样的错误...

编辑1 结束


1
代码完成了吗?它实际上没有将数据从“FSIn”复制到“Stream”。 - aaz
这就是让我困惑的地方... 在我使用它的另一个应用程序中,它运行得非常完美。虽然我对加密还比较新,但我只是在这里尝试和调整。 - Ortund
2个回答

1

我认为有几个问题需要解决。首先,现在你已经将FSOut更改为FSIn,但似乎从代码结构来看,你似乎使用了其中一个而没有实际使用FSOut。我想你的意图是从一个文件中读取数据并加密或解密到另一个文件。

考虑从头开始使用http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx作为起点,如果你的意图是从一个文件中读取并写入另一个文件,则根据需要进行修改,或者考虑编写一个帮助方法,在内存中创建文件的副本,加密文件,移动它并替换内存文件到起始位置,这样做可以让你利用这段代码处理任何情况,并且不会产生太多额外开销。


您对我所做的事情的理解是完全正确的。这个想法是,当文件被读取或写入时,它将被解密,当读/写操作完成时,它将被加密。 - Logan Young

0

CryptoStream 在数据末尾发出 PKCS#7 样式的填充,这可能包括从一个字节到一个完整的密码块的任何位置,但永远不是零长度;这确保加密流的长度是块大小的倍数,并且可以明确地删除填充。您是否尝试解密无效的加密数据?


由于加密原始文件的Stream = New CryptoStream(FSOut, Rij.CreateEncryptor(Key, IV), CryptoStreamMode.Write)行执行顺利,因此不太可能出现问题。 - Logan Young
@Logan — 它可能会执行,但你怎么知道它是否正常工作?看起来它正在创建一个空文件,这将导致像@Jeffrey描述的那样解密错误。 - aaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接