Cifre un archivo usando File.Encrypt y luego descifre a la secuencia de memoria

Necesito implementar un cifrado de archivo simple y luego descifrarlo, cuando sea necesario, en una secuencia de memoria. La forma más fácil parece hacer esto con File.Encrypt, pero ¿es posible descifrar el archivo en la secuencia de memoria, en lugar de descifrarlo antes de leerlo en la memoria, y así exponerlo por un tiempo?

Y si File.Encrypt no es la mejor manera para este escenario, ¿qué recomendaría?

File.Encrypt es una característica del sistema operativo, pero parece que realmente desea controlar cómo se realiza el cifrado.

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

El cifrado no es para los débiles de corazón. Sin embargo, tenga en cuenta que realmente debería tener un fuerte sentido de la IO y las secuencias de datos regulares antes de intentar esto.

Este fue el primer código de encriptación que escribí: tenga cuidado, aunque es un buen punto de partida para entender lo que sucede, las contraseñas estáticas y las sales estáticas son una mala idea. (Gracias por resaltar este CodesInChaos)

Puede descifrar a cualquier flujo que desee, incluso directamente a un flujo de memoria …

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

donde el cifrado es uno de estos:

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

La implementación de Crypto es engañosamente sencilla y, en realidad, bastante tediosa, hay muchos detalles, y los detalles erróneos son, por lo general, lo que se aprovecha de la seguridad. La mejor práctica es usar un marco de cifrado de alto nivel que oculte estos detalles ivs, sales, mac, comparaciones, relleno, rotación de claves, y si bien no es improbable que los marcos de alto nivel tengan los detalles incorrectos, cuando lo hacen, los encuentran. y arreglado, los fragmentos de código en el desbordamiento de stack generalmente no lo hacen.

He estado portando el marco de Google Keyczar para que existiera una biblioteca de alto nivel para C #.

Keyczar-dotnet

Y es utilizable para cifrar y descifrar flujos de io.

Instala en tu proyecto con nuget.

 PM> Install-Package Keyczar -Pre 

Luego crea tu conjunto de claves. (Al tener un archivo de conjunto de claves separado, le brinda la capacidad de rotar claves en el futuro y evita que codifique accidentalmente algo que nunca debería ser codificado).

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

Luego, en su código, puede usar cualquier flujo de IO que desee para el cifrado:

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

y descifrado:

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