Encrypt the file using File.Encrypt, and then decrypt it in the memory stream

I need to implement simple file encryption, and then, if necessary, decrypt it in the memory stream. The easiest way, apparently, is to do this with File.Encrypt, but is it possible to decrypt the file in the memory stream, rather than decrypt the file before reading it into the memory stream and thereby expose it?

And if File.Encrypt is not the best way for this scenario, what would you recommend?

+4
source share
3 answers

File.Encrypt is an OS feature, but it looks like you really want to control how encryption is performed.

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

Encryption is not for the faint of heart. Be warned though, you really should have a strong sense of regular I / O and data streams before you try.

+2
source

This was the first encryption code I wrote - be warned, although a good starting point for understanding what is happening, static passwords and static salts is a bad idea! (thanks for highlighting this CodesInChaos)

You can decrypt any stream that you like, including directly into the memory stream ...

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

where encryption is one of the following:

 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; } } 
+1
source

Implementing Crypto is deceptively easy, and actually quite tedious, there are a lot of details, and the details are wrong, as a rule, they use a security vulnerability. The best practice is to use a high-level encryption system that hides this ivs, salt, mac data, comparisons, additions, key rotation, and although it is unlikely for high-level frameworks that the details are incorrect when they do, they are detected and fixed, fragments code when stack overflows usually do not work.

I ported the Google Keyczar framework , so such a high-level library would exist for C #.

Keyczar-dotnet

And it can be used to encrypt and decrypt io streams.

Install nuget in your project

 PM> Install-Package Keyczar -Pre 

Then create your own set of keys. (Having a separate key set file, it gives you the ability to rotate keys in the future and prevents you from accidentally hard-coding something that should never be hard-coded.)

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

Then in your code, you can use any I / O stream you want for both encryption:

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

and decryption:

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

All Articles