c# - How to encrpyt / decrypt data in chunks? -
i'm quite new c# , encryption please have patience me. want save binary data ("objects" - in fact parts of objects, can't / don't use serialization, binarywriter , similar) , want encrypt in memory , write using filestream. @ first wanted use sort of xor didn't know easy break, changed code use aes.
the thing have relatively large files , quite need change or read 32 bytes of data. must capable of encrypting 1 chunk of data , capable of decrypting desired chunks of data. came following solution.
when saving data loop through data , inside loop encrypt chunk of data , write file. while reading, have loop reads chunks of data , inside loop have declare decryptor, find inefficient.
here's code encryption & saving:
//setup file stream 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 , iv hardcoded enable easier debugging , solving problems, once work i'll change way key , iv generated.
here's code 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 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 thing find inefficient create decryptor in loop. there quite lot of data. if create before entering loop can't decrypt , have change encryption (declare encryption stream , memory stream before loop), can't encrypt / decrypt desired chunk of data. there aren't many files require random reading / writing. instance @ files i'll want read position till end of file, can quite lot.
what's view on this? there better way achieve this? maybe different encryption algorithm (in beginning wanted use sort of xor found out easy "crack") ?
p.s. want encrypt in memory , must use seekable streams.
if want full random access, ecb way go (as earlier answer recommends). not need recreate encryption stream each block, because doesn't use iv , encrypting block doesn't permute stream (unlike other modes cryptotext depends on previous blocks or position of block in stream). wikipedia has nice illustration (the ciphertux picture) of 1 of problems mode.
if file logically consists of larger chunks (such database records or disk sectors in virtual disks), should consider encrypting them units. in cbc mode generate new random iv each chunk each time write , store block (thus using additional 32 bytes of storage per chunk), , need rewrite entire chunk if single byte changes, security better.
Comments
Post a Comment