我以前写过一个库,它使用与下面的类代码相同的逻辑,但当它解密文件时,它会将其解密到光盘上,并提供是否删除加密版本的选项。我正在尝试添加一个选项,将文件解密到内存中,这样我就可以将文件捕获为字节(),并将字节发送到服务。很明显,我可以将文件解密到光盘上,读取文件流,将其转换为字节(),删除解密后的版本(因为我必须对光盘上的文件进行加密)。。。。一次又一次地创建一个删除文件,可能会导致磁盘碎片,等等,所以我只想将文件解密到内存中。无论如何,这成功地将文件解密为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
更新:
我添加了加密流。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
完成所有块的编写后,需要调用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);
}