RijndaelManaged Cryptostream 将文件从光盘解密到内存中
我有一个我不久前编写的库,它使用与下面的类代码相同的逻辑,但是当它解密文件时,它将它解密到光盘上,并提供是否删除加密版本的选项。我正在尝试添加一个选项来将文件解密到内存中,以便我可以将文件捕获为 byte() 并将字节发送到服务。显然,我可以将文件解密到光盘上,读取文件流,将其转换为 byte(),删除解密版本(因为我必须将光盘上的文件加密)....一遍又一遍地创建删除文件,除其他外,可能会导致光盘碎片,因此我想将文件解密到内存中。无论如何,这成功地将文件解密到内存流变量中,但是当我将字节导入文件查看器时,它告诉我文件格式无法识别。有谁知道我在这里做错了什么?
这是我到目前为止的代码:
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 和密钥方法作为解密...
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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
写完所有块后,需要调用 cryptoStream.FlushFinalBlock();
题外话:
这是一个用于获取算法的密钥和 IV 的示例
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