【问题标题】:Index out of range when decrypting a file解密文件时索引超出范围
【发布时间】:2011-02-16 22:16:48
【问题描述】:

我真的不确定这里发生了什么。我的应用程序正在正确加密文件且没有问题,但在尝试解密同一文件时抛出 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 是 抓到消息="索引在外面 数组的边界。”
来源="mscorlib" 堆栈跟踪: 在 System.Security.Cryptography.RijndaelManagedTransform.DecryptData(字节 [] 输入缓冲区,Int32 输入偏移量,Int32 输入计数,字节 []& 输出缓冲区, Int32 outputOffset, PaddingMode paddingMode, 布尔型 fLast) 在 System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(字节 [] 输入缓冲区,Int32 输入偏移量,Int32 输入计数) 在 System.Security.Cryptography.CryptoStream.FlushFinalBlock() 在 System.Security.Cryptography.CryptoStream.Dispose(布尔 处置) 在 System.IO.Stream.Close() 在 Crypt.EncryptDecrypt(字符串操作,字符串 InFile,字符串 OutFile) 在 D:\Development\Projects\Web\WebSite1\App_Code\Crypt.vb:line 34 内部异常:

任何帮助将不胜感激。

编辑 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="索引超出了数组的范围。" 来源="mscorlib" 堆栈跟踪: 在 System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] > inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 > outputOffset, PaddingMode paddingMode, Boolean fLast) 在 System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(字节 [] > inputBuffer,Int32 inputOffset,Int32 inputCount) 在 System.Security.Cryptography.CryptoStream.FlushFinalBlock() 在 System.Security.Cryptography.CryptoStream.Dispose(布尔处理) 在 System.IO.Stream.Close() 在 Crypt.EncryptDecrypt(String Action, String InFile, String OutFile) in > D:\Development\Projects\Web\WebSite1\App_Code\Crypt.vb:line 34 内部异常:

在我看来,这是同样的错误......

结束编辑 1

【问题讨论】:

  • 代码是否完整?它实际上并没有将数据从FSIn 复制到Stream
  • 这让我感到困惑......它在我使用它的另一个应用程序中完美运行。不过,我对加密还很陌生,所以我只是在这里和那里修修补补。

标签: security encryption filestream rijndaelmanaged


【解决方案1】:

嗯,我认为有几件事需要解决。一方面,由于您已将 FSOut 更改为 FSIn,因此似乎从未实际使用过 FSOut。您似乎正在使用其中一个,但从代码的结构来看,我认为您的意图是获取一个文件并将数据加密或解密到另一个文件。

考虑从头开始使用http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx 作为起点,如果您的意图是让它从一个文件中读取并写入另一个文件,请根据您认为合适的方式修改它,或者考虑使用一个帮助方法来创建一个在内存中复制文件,加密文件,移动它并将内存中的文件替换到起始位置,这样做可以让您在任何一种情况下都利用此代码,并且不会产生太多额外的开销。

【讨论】:

  • 你对我所做的事情是 100% 正确的。这个想法是文件在被读取或写入时会被解密,并在读取/写入操作完成时被加密。
【解决方案2】:

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

【讨论】:

  • 不太可能,因为加密原始文件的Stream = New CryptoStream(FSOut, Rij.CreateEncryptor(Key, IV), CryptoStreamMode.Write) 行执行时没有发生意外。
  • @Logan — 它可以执行,但你怎么知道它工作正常?看起来它正在创建一个空文件,由于@Jeffrey 所描述的原因,这会在解密时出错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 2015-10-23
  • 1970-01-01
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多