簡體   English   中英

使用File.Encrypt加密文件,然后將其解密為內存流

[英]Encrypt a file using File.Encrypt and then Decrypt it to memory stream

我需要實現一個簡單的文件加密,然后在需要時將其解密到內存流。 最簡單的方法似乎是使用File.Encrypt執行此操作,但是是否可以將文件解密為內存流,而不是在將文件讀取到內存流之前解密文件,從而將文件暴露一段時間?

如果File.Encrypt不是這種情況的最佳方式,你會推薦什么?

File.Encrypt是一個操作系統功能,但聽起來你真的想控制加密的方式。

http://msdn.microsoft.com/en-us/library/system.io.file.encrypt.aspx

// This is where the data will be written do.
MemoryStream dataStream = new MemoryStream();

// The encryption vectors
byte[] key = {145,12,32,245,98,132,98,214,6,77,131,44,221,3,9,50};
byte[] iv  = {15,122,132,5,93,198,44,31,9,39,241,49,250,188,80,7};

// Build the encryption mathematician
using (TripleDESCryptoServiceProvider encryption = new TripleDESCryptoServiceProvider())
using (ICryptoTransform transform = encryption.CreateEncryptor(key, iv))
using (Stream encryptedOutputStream = new CryptoStream(dataStream, transform, CryptoStreamMode.Write))
using (StreamWriter writer = new StreamWriter(encryptedOutputStream))
{
    // In this block, you do your writing, and it will automatically be encrypted
    writer.Write("This is the encrypted output data I want to write");
}

加密不適合膽小的人。 但是要預先警告,在嘗試此操作之前,您確實應該對常規IO和數據流有強烈的感覺。

這是我寫的第一個加密代碼 - 被警告,雖然一個很好的起點來了解正在發生的事情,靜態密碼和靜態鹽是一個壞主意! (感謝您突出顯示此CodesInChaos)

您可以解密到您喜歡的任何流,包括直接到內存流......

FileInfo file = new FileInfo("SomeFile");
using (FileStream inFs = file.OpenRead())
{
    using (MemoryStream outMs = new MemoryStream())
    {
        encryption.Decrypt(inFs, outMs);                    

        BinaryFormatter bf = new BinaryFormatter();
        targetType target= bf.Deserialize(outMs) as targetType;
    }
}

加密是其中之一:

public class EncryptionHelper
{        
    static SymmetricAlgorithm encryption; 
    static string password = "password";
    static string salt = "this is my salt. There are many like it, but this one is mine.";

    static EncryptionHelper()
    {
        encryption = new RijndaelManaged();
        Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(salt));

        encryption.Key = key.GetBytes(encryption.KeySize / 8);
        encryption.IV = key.GetBytes(encryption.BlockSize / 8);
        encryption.Padding = PaddingMode.PKCS7;
    }

    public void Encrypt(Stream inStream, Stream OutStream)
    {
        ICryptoTransform encryptor = encryption.CreateEncryptor();
        inStream.Position = 0;
        CryptoStream encryptStream = new CryptoStream(OutStream, encryptor, CryptoStreamMode.Write);
        inStream.CopyTo(encryptStream);
        encryptStream.FlushFinalBlock();

    }


    public void Decrypt(Stream inStream, Stream OutStream)
    {
        ICryptoTransform encryptor = encryption.CreateDecryptor();
        inStream.Position = 0;
        CryptoStream encryptStream = new CryptoStream(inStream, encryptor, CryptoStreamMode.Read);
        encryptStream.CopyTo(OutStream);
        OutStream.Position = 0;  
    }
}

實現Crypto看似簡單,實際上相當乏味,有很多細節,而細節錯誤通常是利用安全性的明智之舉。 最好的做法是使用高級加密框架來隱藏這些細節ivs,salt,mac,比較,填充,鍵旋轉,雖然高級框架不太可能讓細節出錯,但是當它們發生時,它們會被發現並修復,堆棧溢出的代碼片段一般不會。

我一直在移植Google Keyczar框架,因此C#會存在這樣一個高級庫。

Keyczar,DOTNET

它可用於加密和解密io流。

使用nuget在項目中安裝

PM> Install-Package Keyczar -Pre

然后創建您的密鑰集。 (通過使用單獨的密鑰集文件,它使您能夠在將來旋轉密鑰,並防止您意外地硬編碼不應該硬編碼的內容。)

PM> KeyczarTool.exe create --location=path_to_key_set --purpose=crypt
PM> KeyczarTool.exe addkey --location=path_to_key_set --status=primary

然后在您的代碼中,您可以使用任何所需的IO流進行加密:

using(var encrypter = new Encrypter("path_to_key_set"))
{
     encrypter.Encrypt(plaintextStream, ciphertextStream);
}

和解密:

using(var crypter = new Crypter("path_to_key_set"))
{
     crypter.Decrypt(ciphertextStream, plaintextStream);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM