使用File.Encrypt加密文件,然后将其解密为内存流

我需要实现一个简单的文件加密,然后在需要时将其解密到内存流。 最简单的方法似乎是使用File.Encrypt执行此操作,但是是否可以将文件解密为内存流,而不是在将文件读取到内存流之前解密文件,从而将文件暴露一段时间?

如果File.Encrypt不是这种情况的最佳方式,你会推荐什么?

File.Encrypt是一个操作系统function,但听起来你真的想控制加密的方式。

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); }