C
C#15mo ago
Jake

Can't read from MemoryStream from current position

I am trying to decrypt a file in c# and I have the cipher in a memory stream alongside the key and iv. I want to only get the cipher which starts at 256, and after reading the Key and IV the position is 256. I have tried using memoryStream.toArray() but that ignores the position completely.
33 Replies
mtreit
mtreit15mo ago
What do you mean you "can't read" ? @Jakee are you confusing bit length with byte length? Key and IV combined should be 256 bits, but memory stream position is in bytes not bits.
Jake
Jake15mo ago
I might be But my key and iv are encrypted and I'm pretty sure there size is 128 bytes each
mtreit
mtreit15mo ago
No, it should be 16 bytes 128 bits
Jake
Jake15mo ago
Can't use memoryStream.ToArray() because it gets everything and idk Im using aes to encrypt them and it results in them being 128 bytes each then i decrypt and they are back to 32 bytes and 16 bytes respectively key, iv# Basically, I am encrypting the key, iv, and file bytes and putting them into a memory stream (in that order) the size of the encrypted key and iv are 128 each and the size of the encrypted file depends on its unencrypted size (usually just a couple hundred more bytes)
cap5lut
cap5lut15mo ago
so basically ur issue is that u dont know how to read from current stream position to end?
Jake
Jake15mo ago
now I want to get that stuff out of the memory stream and with key and iv its fine I can just memoryStream.Read() but i cant use that for the cipher because i can't make it a set size exactly maybe i am missusing memoryStream.Read()
//1. retrieve the encrypted key and the encrypted iv from the cipher
MemoryStream input = new MemoryStream(cipher);

//1a
byte[] encryptedKey = new byte[128]; //note about 128, get the proper size of the encrytped key after manually debugging the hybridecrypt
input.Read(encryptedKey, 0, encryptedKey.Length);

//1b do the same thing for the iv
byte[] encryptedIV = new byte[128];
input.Read(encryptedIV, 0 , encryptedIV.Length);

//2. read the left data i.e. the encrypted file data (cipher.Length - encryptedkey.length - encrtypediv.length)
//it continues reading the remaining bytes therefore if the enc key and enc iv were 128 bytes each, it means that ToArray will continue reading from position 256 till end of file
byte[] originalFileCipher = input.ToArray();

//3. decrypt asymmetrically using the private key the enc key and enc iv
byte[] decryptedKey = AsymmetricDecrypt(encryptedKey, privateKey);
byte[] decryptedIV = AsymmetricDecrypt(encryptedIV, privateKey);

//4. decrypt symmetrically the originalFileCipherNotIncludingTheSymmKeys using the decrypted key and decrypted iv
byte[] originalBytes = SymmetricDecrypt(originalFileCipher, decryptedKey, decryptedIV);
//1. retrieve the encrypted key and the encrypted iv from the cipher
MemoryStream input = new MemoryStream(cipher);

//1a
byte[] encryptedKey = new byte[128]; //note about 128, get the proper size of the encrytped key after manually debugging the hybridecrypt
input.Read(encryptedKey, 0, encryptedKey.Length);

//1b do the same thing for the iv
byte[] encryptedIV = new byte[128];
input.Read(encryptedIV, 0 , encryptedIV.Length);

//2. read the left data i.e. the encrypted file data (cipher.Length - encryptedkey.length - encrtypediv.length)
//it continues reading the remaining bytes therefore if the enc key and enc iv were 128 bytes each, it means that ToArray will continue reading from position 256 till end of file
byte[] originalFileCipher = input.ToArray();

//3. decrypt asymmetrically using the private key the enc key and enc iv
byte[] decryptedKey = AsymmetricDecrypt(encryptedKey, privateKey);
byte[] decryptedIV = AsymmetricDecrypt(encryptedIV, privateKey);

//4. decrypt symmetrically the originalFileCipherNotIncludingTheSymmKeys using the decrypted key and decrypted iv
byte[] originalBytes = SymmetricDecrypt(originalFileCipher, decryptedKey, decryptedIV);
mtreit
mtreit15mo ago
Memory stream read calls just read from the current stream position, so you just seek to the position you want and then call Read
Jake
Jake15mo ago
after reading the encrypted key and iv I am already at the position I want to be at but idk what parameters to give read to read from where I am till end of line
mtreit
mtreit15mo ago
You pass a buffer into Read and it fills that buffer.
Jake
Jake15mo ago
so literally just input.read(buffer)? I ignore the other parameters? what count should i give it
mtreit
mtreit15mo ago
MemoryStream.Read Method (System.IO)
Reads a sequence of bytes from the current memory stream and advances the position within the memory stream by the number of bytes read.
Jake
Jake15mo ago
Yes but I do not know what maximum to give it then since the file can be any size
mtreit
mtreit15mo ago
Typically you would read in chunks.
cap5lut
cap5lut15mo ago
ur stream has a Length and a Position property so u can compute the size
mtreit
mtreit15mo ago
Rather than try to read an entire file (which could be very large) into a single in-memory array. However in your case you said it's already a memory stream
Jake
Jake15mo ago
so input.Length - input.Position?
cap5lut
cap5lut15mo ago
but as mreit said, usually chunk sized because u dont want a 4gb file in memory ;p
mtreit
mtreit15mo ago
So it's already in memory
Jake
Jake15mo ago
its a school project it will never be given something that large I am testing on a 36kb file
mtreit
mtreit15mo ago
So...if you really need to, yes you can just compute the remaining size by subtracting what you've read already.
Jake
Jake15mo ago
They just want to test us on encryption Okay I'll try it
Jake
Jake15mo ago
Jake
Jake15mo ago
woops 1 sec
Jake
Jake15mo ago
Jake
Jake15mo ago
what do i set it as
mtreit
mtreit15mo ago
You need to create an instance of the correct length
byte[] originalFileCipher = new byte[length];
byte[] originalFileCipher = new byte[length];
Jake
Jake15mo ago
yeah
cap5lut
cap5lut15mo ago
byte[] originalFileCipher; is just declaring a variable, it has no value yet, but u try to use it as one, so its complaining
Jake
Jake15mo ago
Ok it worked the file successfully decrypted and I can see its contents Thanks guys :) yes ik just asking what I should put lol
mtreit
mtreit15mo ago
Just FYI, there is no good reason to encrypt the IV.
cap5lut
cap5lut15mo ago
usually u do it in chunks, as mtreit already mentioned, because u dont want ur ram to explode if the file is large
Jake
Jake15mo ago
Yea we know that is a risk but my lecturer won't try that we are just getting tested on encryption etc its for securing applications
mtreit
mtreit15mo ago
Not sure what you mean by risk. I'm just saying that even in real-world encryption the initialization vector is typically not encrypted. It's not sensitive information. Anyway, that's just an aside.