Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I need to implement a simple file encryption and then decrypt it, when needed, to a memory stream. The easiest way seems to do this with File.Encrypt, but is it possible to decrypt the file to memory stream, instead of decrypting the file before reading it to memory stream, and thus exposing it for a while?

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

like image 475
user1307346 Avatar asked Feb 08 '13 17:02

user1307346


2 Answers

File.Encrypt is an OS feature but it sounds like really you want to control how the encryption is done.

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 forewarned though, you really should have a strong sense of regular IO and data streams before you attempt this though.

like image 173
sircodesalot Avatar answered Sep 21 '22 00:09

sircodesalot


Implementing Crypto deceptively easy, and actually rather tedious, there are a lot of details, and the details wrong are usually what's exploited security wise. The best practice is to use a high level encryption framework that hides these details ivs, salts, mac, comparisons, padding, key rotation, and while it's not improbable for high level frameworks to have the details wrong, when they do, they get found and fixed, the code snippets on stack overflow generally do not.

I have been porting the Google Keyczar framework so such a high level library would exist for C#.

Keyczar-dotnet

And it is usable for encrypting and decrypting io streams.

Install in your project with nuget

PM> Install-Package Keyczar -Pre

Then create your key set. (by having a separate key set file, it gives you the ability to rotating keys in the future and prevents you from accidentally hard coding something that should not ever 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 IO 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);
}
like image 38
jbtule Avatar answered Sep 21 '22 00:09

jbtule