c# - Decrypting CryptoStream into MemoryStream -
i have written process file encrypted , uploaded azure, download process has decrypted fails "padding invalid , cannot removed" error, or "length of data decrypt invalid." error.
i've tried numerous solutions online, including c# decrypting mp3 file using rijndaelmanaged , cryptostream, none of them seem work , end bouncing , forth between these 2 errors. encryption process uses same key/iv pair decryption uses, , since decrypt portion of stream feel that's working fine - ends dying above errors.
here code, ideas? please note 3 variants (cryptostream.copyto(decryptedstream)
, do {}
, while
) aren't run - here show options i've tried, of fail.
byte[] encryptedbytes = null; using (var encryptedstream = new memorystream()) { //download azure cloudblockblob.downloadtostream(encryptedstream); //reset positioning reading out encryptedstream.position = 0; encryptedbytes = encryptedstream.converttobytearray(); } //used blob stream azure using (var encryptedstream = new memorystream(encryptedbytes)) { //stream decrypted contents stored using (var decryptedstream = new memorystream()) { using (var aes = new rijndaelmanaged { keysize = 256, key = blobkey.key, iv = blobkey.iv }) { using (var decryptor = aes.createdecryptor()) { //decrypt stream , write parent stream using (var cryptostream = new cryptostream(encryptedstream, decryptor, cryptostreammode.read)) { //fails here "length of data decrypt invalid." error cryptostream.copyto(decryptedstream); int data; //fails here "length of data decrypt invalid." error after loops number of times, //implying in fact decrypting part of it, not { data = cryptostream.readbyte(); decryptedstream.writebyte((byte)cryptostream.readbyte()); } while (!cryptostream.hasflushedfinalblock); //fails here "length of data decrypt invalid." error after loops number of times, //implying in fact decrypting part of it, not while ((data = cryptostream.readbyte()) != -1) { decryptedstream.writebyte((byte)data); } } } } //reset position in prep reading decryptedstream.position = 0; return decryptedstream.converttobytearray(); } }
one of comments mentioned wanting know converttobytearray
is, , it's simple extension method:
/// <summary> /// converts stream byte array. /// </summary> /// <param name="stream">the stream convert.</param> /// <returns>a byte[] array representing current stream.</returns> public static byte[] converttobytearray(this stream stream) { byte[] buffer = new byte[16 * 1024]; using (memorystream ms = new memorystream()) { int read; while ((read = stream.read(buffer, 0, buffer.length)) > 0) { ms.write(buffer, 0, read); } return ms.toarray(); } }
the code never reaches though - dies before can ever point.
after lot of , forth various blogs, found had couple of errors in above code nailing me. first, encryption process incorrectly writing array - wrapped cryptostream
instance, wasn't utilizing writing unencrypted data azure. here proper route go (filekey
part of custom class created generate key/iv pairs, wherever referenced can changed built-in process rijndaelmanaged
or else you'd utilize coming key/iv pair):
using (var aes = new rijndaelmanaged { keysize = 256, key = filekey.key, iv = filekey.iv }) { using (var encryptedstream = new memorystream()) { using (icryptotransform encryptor = aes.createencryptor()) { using (cryptostream cryptostream = new cryptostream(encryptedstream, encryptor, cryptostreammode.write)) { using (var originalbytestream = new memorystream(file.file.data)) { int data; while ((data = originalbytestream.readbyte()) != -1) cryptostream.writebyte((byte)data); } } } var encryptedbytes = encryptedstream.toarray(); return encryptedbytes; } }
second, since encryption process involves multiple steps (three total keys per file - container, filename , file itself), when tried decrypt, using wrong key (which seen above when referenced blobkey
decrypt, key used encrypting filename , not file itself. proper decryption method was:
//used blob stream azure using (var encryptedstream = new memorystream(encryptedbytes)) { //stream decrypted contents stored using (var decryptedstream = new memorystream()) { using (var aes = new rijndaelmanaged { keysize = 256, key = blobkey.key, iv = blobkey.iv }) { using (var decryptor = aes.createdecryptor()) { //decrypt stream , write parent stream using (var cryptostream = new cryptostream(encryptedstream, decryptor, cryptostreammode.read)) { int data; while ((data = cryptostream.readbyte()) != -1) decryptedstream.writebyte((byte)data); } } } //reset position in prep reading decryptedstream.position = 0; return decryptedstream.converttobytearray(); } }
i had looked azure encryption extensions (http://www.stefangordon.com/introducing-azure-encryption-extensions/), little more local file-centric interested - on end streams/in-memory only, , retrofitting utility going more work worth.
hopefully helps looking encrypt azure blobs 0 reliance on underlying file system!
Comments
Post a Comment