RijndaelManaged Cryptostream将文件从光盘解密到内存中

时间:2012-01-27 00:18:49

标签: .net encryption rijndael rijndaelmanaged

我有一个我曾经写过的库,它使用与下面的类代码相同的逻辑,但是当它解密文件时,它会将其解密到光盘上,并提供删除加密版本的选项。我正在尝试添加一个选项来将文件解密到内存中,这样我就可以将文件捕获为byte()并将字节发送到服务。我显然可以将文件解密到光盘上,读取文件流,将其转换为byte(),删除解密版本(因为我必须将文件保存在光盘上加密)....一遍又一遍地创建删除文件,除其他外,可能导致磁盘碎片,所以我想将文件解密到内存中。 Anways,这成功地将文件解密到memorystream变量中,但是当我将字节变成文件查看器时,它告诉我文件格式无法识别。有谁知道我在这里做错了什么?

这是我到目前为止的代码:

Public Class EncryptionFactory     

Private Shared fsInput As FileStream

            Public Shared Function GetDecryptedFile(ByVal password As String, ByVal encryptedFilePath As String) As Byte()

                Return DecryptFile(encryptedFilePath, Key(password), IV(password))

            End Function


            Private Shared Function DecryptFile(ByVal strInputFile As String, ByVal bytKey As Byte(), ByVal bytIV As Byte()) As Byte()

                fsInput = New FileStream(strInputFile, FileMode.Open, FileAccess.Read)
                Dim memoryStream As MemoryStream
                memoryStream = New MemoryStream()
                Dim array As Byte() = New Byte(&H1001 - 1) {}
                Dim num2 As Long = 0
                Dim length As Long = fsInput.Length
                Dim managed As New RijndaelManaged
                Dim stream As New CryptoStream(memoryStream, managed.CreateDecryptor(bytKey, bytIV), CryptoStreamMode.Write)

                Do While (num2 < length)
                    Dim count As Integer = fsInput.Read(array, 0, &H1000)
                    stream.Write(array, 0, count)
                    num2 = (num2 + count)
                Loop

                Dim data As Byte() = memoryStream.ToByte()

                fsInput.Close()
                fsInput.Dispose()
                memoryStream.Close()
                memoryStream.Dispose()

                Return data

            End Function

            Private Shared Function Key(ByVal strPassword As String) As Byte()
                Dim num5 As Integer
                Dim chArray As Char() = strPassword.ToCharArray
                Dim buffer As Byte() = New Byte((chArray.GetUpperBound(0) + 1) - 1) {}
                Dim upperBound As Integer = chArray.GetUpperBound(0)
                Dim i As Integer = 0
                Do While (i <= upperBound)
                    buffer(i) = CByte(Strings.Asc(chArray(i)))
                    i += 1
                Loop
                Dim buffer3 As Byte() = New SHA512Managed().ComputeHash(buffer)
                Dim buffer2 As Byte() = New Byte(&H20 - 1) {}
                Dim index As Integer = 0
                Do
                    buffer2(index) = buffer3(index)
                    index += 1
                    num5 = &H1F
                Loop While (index <= num5)
                Return buffer2
            End Function

            Private Shared Function IV(ByVal strPassword As String) As Byte()
                Dim num5 As Integer
                Dim chArray As Char() = strPassword.ToCharArray
                Dim buffer As Byte() = New Byte((chArray.GetUpperBound(0) + 1) - 1) {}
                Dim upperBound As Integer = chArray.GetUpperBound(0)
                Dim i As Integer = 0
                Do While (i <= upperBound)
                    buffer(i) = CByte(Strings.Asc(chArray(i)))
                    i += 1
                Loop
                Dim buffer3 As Byte() = New SHA512Managed().ComputeHash(buffer)
                Dim buffer2 As Byte() = New Byte(&H10 - 1) {}
                Dim index As Integer = &H20
                Do
                    buffer2((index - &H20)) = buffer3(index)
                    index += 1
                    num5 = &H2F
                Loop While (index <= num5)
                Return buffer2
            End Function



        End Class

更新:

我添加了cryptostream.FlushFinalBlock()

这仍然无法正常工作...我觉得这不是一直到最后都在阅读流。

Private Shared Function DecryptFile(ByVal strInputFile As String, ByVal bytKey As Byte(), ByVal bytIV As Byte()) As Byte()

    fsInput = New FileStream(strInputFile, FileMode.Open, FileAccess.Read)
    Dim memoryStream As MemoryStream
    memoryStream = New MemoryStream()
    Dim array As Byte() = New Byte(&H1001 - 1) {}
    Dim num2 As Long = 0
    Dim length As Long = fsInput.Length
    Dim managed As New RijndaelManaged
    Dim stream As New CryptoStream(memoryStream, managed.CreateDecryptor(bytKey, bytIV), CryptoStreamMode.Write)

    Do While (num2 < length)
        Dim count As Integer = fsInput.Read(array, 0, &H1000)
        stream.Write(array, 0, count)
        num2 = (num2 + count)
    Loop

    stream.FlushFinalBlock()

    Dim data As Byte() = memoryStream.ToByte()

    fsInput.Close()
    fsInput.Dispose()
    memoryStream.Close()
    memoryStream.Dispose()

    Return data

End Function

更新:

这是我的“加密”方法,使用与解密相同的IV和Key方法......

Friend Sub EncryptFile(ByVal strInputFile As String, ByVal strOutputFile As String, ByVal bytKey As Byte(), ByVal bytIV As Byte(), ByVal deleteOrig As Boolean)
    Me.fsInput = New FileStream(strInputFile, FileMode.Open, FileAccess.Read)
    Me.fsOutput = New FileStream(strOutputFile, FileMode.OpenOrCreate, FileAccess.Write)
    Me.fsOutput.SetLength(0)
    Dim array As Byte() = New Byte(&H1001  - 1) {}
    Dim num2 As Long = 0
    Dim length As Long = Me.fsInput.Length
    Dim managed As New RijndaelManaged
    Dim stream As New CryptoStream(Me.fsOutput, managed.CreateEncryptor(bytKey, bytIV), CryptoStreamMode.Write)
    Do While (num2 < length)
        Dim count As Integer = Me.fsInput.Read(array, 0, &H1000)
        stream.Write(array, 0, count)
        num2 = (num2 + count)
    Loop
    stream.Close
    Me.fsInput.Close
    Me.fsOutput.Close
    If deleteOrig Then
        Dim info As New FileInfo(strInputFile)
        If ((info.Attributes And FileAttributes.ReadOnly) > 0) Then
            info.Attributes = (info.Attributes Xor FileAttributes.ReadOnly)
            File.Delete(strInputFile)
        Else
            info.Delete
        End If
    End If
End Sub

最后更新:

这是成功的内存代码的解密文件:

Private Shared Function DecryptFile(ByVal strInputFile As String, ByVal bytKey As Byte(), ByVal bytIV As Byte()) As Byte()

        fsInput = New FileStream(strInputFile, FileMode.Open, FileAccess.Read)
        Dim memoryStream As MemoryStream
        memoryStream = New MemoryStream()
        Dim array As Byte() = New Byte(&H1001 - 1) {}
        Dim num2 As Long = 0
        Dim length As Long = fsInput.Length
        Dim managed As New RijndaelManaged
        Dim stream As New CryptoStream(memoryStream, managed.CreateDecryptor(bytKey, bytIV), CryptoStreamMode.Write)

        Do While (num2 < length)
            Dim count As Integer = fsInput.Read(array, 0, &H1000)
            stream.Write(array, 0, count)
            num2 = (num2 + count)
        Loop

        stream.FlushFinalBlock()
        stream.Dispose()

        Dim data As Byte() = memoryStream.ToArray()

        fsInput.Close()
        fsInput.Dispose()
        memoryStream.Close()
        memoryStream.Dispose()

        Return data

    End Function

1 个答案:

答案 0 :(得分:1)

完成所有块的编写后,需要调用cryptoStream.FlushFinalBlock();

关闭主题: 以下是使用获取算法的密钥和IV的示例

private void SetAlgorithmKey(SymmetricAlgorithm algorithm, string password, string salt, int iterationCount)
{
    byte[] saltBytes = string.IsNullOrEmpty(salt) ? new byte[0] : Encoding.ASCII.GetBytes(salt);

    // The salt size must be 8 bytes or larger.
    if (saltBytes.Length < 8)
    {
        byte[] newSaltBytes = new byte[8];
        Array.Copy(saltBytes, newSaltBytes, saltBytes.Length);
        for (int i = saltBytes.Length; i < 8; i++)
        {
            newSaltBytes[i] = 0; // pad with zeros?
        }

        saltBytes = newSaltBytes;
    }

    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, saltBytes, iterationCount);
    algorithm.Key = pdb.GetBytes(algorithm.KeySize / 8);
    algorithm.IV = pdb.GetBytes(algorithm.BlockSize / 8);
}