我有一個庫,我回寫時使用了與下面的類代碼相同的邏輯,但是當它解密文件時,它將它解密到光盤上,然後給出一個選項刪除加密版本。我試圖添加一個選項來將文件解密到內存中,以便我可以將該文件捕獲爲byte()並將字節發送到服務。我明顯可以將文件解密到光盤上,讀取文件流,將其轉換爲字節(),刪除解密版本(因爲我必須保留磁盤上的文件加密)....一遍又一遍創建刪除文件,可能會導致光盤碎片等等,所以我只想將文件解密到內存中。總之,這成功地將文件解密爲內存流變量,但是當我將字節啞到文件查看器時,它告訴我文件格式不被識別。有誰知道我在這裏做錯了嗎?RijndaelManaged Cryptostream將文件從光盤解密到內存中
下面的代碼我到目前爲止:
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:
我增加了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
UPDATE:
下面是我的 「加密」 的方法,使用相同的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
請看我更新的例子......我想你的建議,而我得到的相同的結果...我沒有正確實施你的建議嗎? – wakurth 2012-01-27 01:21:18
如果你使用.NET 4,你可以使用'fsInput.CopyTo(stream);'而不是循環。當你加密文件時,是否調用FlushFinalBlock? – 2012-01-27 01:32:15
此外,我不知道你從哪裏得到你的密鑰和IV代碼。有一個更好的方法使用'System.Security.Cryptography.Rfc2898DeriveBytes' – 2012-01-27 01:33:45