2012-01-27 75 views
0

我有一個庫,我回寫時使用了與下面的類代碼相同的邏輯,但是當它解密文件時,它將它解密到光盤上,然後給出一個選項刪除加密版本。我試圖添加一個選項來將文件解密到內存中,以便我可以將該文件捕獲爲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 

回答

1

寫完所有塊後,您需要調用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); 
} 
+0

請看我更新的例子......我想你的建議,而我得到的相同的結果...我沒有正確實施你的建議嗎? – wakurth 2012-01-27 01:21:18

+0

如果你使用.NET 4,你可以使用'fsInput.CopyTo(stream);'而不是循環。當你加密文件時,是否調用FlushFinalBlock? – 2012-01-27 01:32:15

+0

此外,我不知道你從哪裏得到你的密鑰和IV代碼。有一個更好的方法使用'System.Security.Cryptography.Rfc2898DeriveBytes' – 2012-01-27 01:33:45

相關問題