RijndaelManaged Cryptostream для расшифровки файла с диска в память - PullRequest
0 голосов
/ 27 января 2012

У меня есть библиотека, которую я недавно написал, которая использует ту же логику, что и код класса ниже, но когда он расшифровывает файл, он расшифровывает его на диск и дает возможность удалить зашифрованную версию или нет.Я пытаюсь добавить опцию, чтобы расшифровать файл в памяти, чтобы я мог захватить файл как byte () и отправить байты в службу.Очевидно, что я могу расшифровать файл на диск, прочитать поток файла, преобразовать его в byte (), удалить дешифрованную версию (потому что я должен сохранять файлы на диске в зашифрованном виде) .... создавая удаление файлов снова и снова,кроме всего прочего, может вызвать фрагментацию диска, поэтому я хотел бы просто расшифровать файл в памяти.В любом случае, это успешно расшифровывает файл в переменную 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 Ответ

1 голос
/ 27 января 2012

После того как вы закончили писать все блоки, вам нужно вызвать 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);
}
...