I'm quite new to C# and encryption so please have patience with me. I want to save some binary data ("objects" - in fact mostly only parts of objects, thus I can't / don't use serialization, BinaryWriter and similar) and I want to encrypt it in memory and then write it using FileStream. At first I wanted to use some sort of Xor but I didn't know that it is so easy to break, now I changed code to use Aes.
The thing is that I will have some relatively large files and quite often I will only need to change or read like 32 bytes of data. Thus I must be capable of encrypting only one chunk of data and also capable of decrypting only desired chunks of data. For now I came up only with the following solution.
When saving data I loop through all the data and inside the loop encrypt a chunk of data and write it to a file. While reading, I have loop which reads chunks of data and inside the loop I have to declare the decryptor, which I find very inefficient.
Here's the code for encryption & saving:
//setup file stream for saving data
FileStream fStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
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 };
aes.Padding = PaddingMode.None;
ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);
foreach(....)
{
//data manipulation
//encryption
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write))
c.Write(data, 0, data.Length);
byte[] original = new byte[32];
original = m.ToArray();
fStream.Write(original, 0, original.Length);
}
The key and iv is hardcoded just to enable easier debugging and solving problems, once this will work I'll change the way key and iv are generated.
Here's the code for reading & decryption: FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
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 };
aes.Padding = PaddingMode.None;
//reading
while (numBytesToRead > 0)
{
byte[] original = new byte[32];
byte[] data = new byte[32];
int len = fStream.Read(original, 0, 32);
//error checking ...
//decryption
ICryptoTransform decryptor = aes.CreateDecryptor(key, iv); //this is a slow operation
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write))
c.Write(original, 0, original.Length);
data = m.ToArray();
//data manipulation ...
}
Well the thing is that I find it very inefficient to create a decryptor in a loop. There will be quite a lot of data. If I create it before entering the loop then I can't decrypt properly and have to change encryption (declare encryption stream and memory stream before loop), but then I can't encrypt / decrypt only desired chunk of data. Also there aren't many files which would only require random reading / writing. For instance at some files I'll want to read from a certain position till the end of file, which can be quite a lot.
What's your view on this? Is there a better way to achieve this? Maybe different encryption algorithm (in the beginning I wanted to use some sort of xor but I found out it is very easy to "crack") ?
p.s. I want to encrypt in memory and I must use seekable streams.