Question

I have a library I wrote a while back that uses the same logic as the class code below, but when it decrypts a file, it decrypts it onto the disc, and give an option to delete the encrypted version or not. I'm trying to add an option to decrypt the file into memory so I can capture the file as a byte() and send the bytes to a service. I can obviously decrypt the file onto disc, read the file stream, convert it to byte(), delete the decrypted version (because I have to keep the files on disc encrypted).... creating a deleting files over and over again, can cause disc fragmentation, among other things, so I would like to just decrypt the file into memory. Anways, this successfully decrypts the file into the memorystream variable, but when I dumb the bytes into the file viewer, it tells me the file format is not recognized. Does anyone know what I'm doing wrong here?

Here's the code I have so far:

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

UPDATE:

I added the cryptostream.FlushFinalBlock()

this is still not working... I feel like it's just not reading the stream all the way to the end.

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

UPDATE:

Here's in my "Encrypt" Method, using the same IV, and Key methods as the decrypt...

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

Final UPDATE:

Here's the decrypt file to memory code that was successful:

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
Was it helpful?

Solution

After you have finished writing all of the blocks, you need to call cryptoStream.FlushFinalBlock();

Off Topic: Here is an example of using to get the key and IV for your algorithm

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top