I'd like to stream encrypted files from a server. I know that for example RSA supports streaming decryption. I am not sure whether twofish or Rijndael supports it either.

I guess if they do not support, it can be implemented by splitting up the data into chunks with known size and encrypt the actual chunk instead of the whole data. So the result will be something like this:

[enc(chunk(data, 0)), enc(chunk(data, 1)), ... enc(chunk(data, index))]

instead of

[chunk(enc(data), 0)), chunk(enc(data), 1)), ... chunk(enc(data), index))]

Am I right, or were these algorithms designed with streaming support in mind?

To clarify what I meant by "streaming decryption":

Streaming is described in the node.js manual very well, but it is a general concept and a well known Linux feature, so it should not be new to any programmer. It is roughly sending a big file in small chunks, so you can start to work with it (display, transform, etc.) before the whole file arrives and you don't have to keep the entire file in the memory, which reduces memory consumption.

Streaming decryption is using a transform stream to decrypt the data. So you read a small chunk of the ciphertext, decrypt it and write the resulting data chunk to another stream. There can be several problems here, for example the ciphertext has different size than the actual data, so if you want to seek the data you need to convert data index to ciphertext index. Another problem that decrypting a chunk with arbitrary size might not result the same data as you would have by decripting the whole ciphertext and split it up into chunks after that.

  • 1
    Can you clarify what you mean by RSA "supports streaming decryption"? RSA decryption is absurdly slow (for decent key sizes) compared to symmetric algorithms for a given size of message, and works on relatively large blocks of data (based by the key size) compared to a block cipher like Rijndael/AES; you would never use it to stream anything. – CBHacking Nov 18 '17 at 4:14
  • @You might be right, I read this question now: crypto.stackexchange.com/questions/47801/… . But there appears to be a - probably failed - attempt to use RSA for video streaming: blog.rsaplay.com/using-rsa-encryption-to-secure-video Another attempt is here: github.com/substack/rsa-stream Not that I did not examine how it is implemented, so I might be wrong about this RSA + stream support thing. – inf3rno Nov 18 '17 at 8:32
  • 2
    I don't think you should take that as a personal insult. I based my answer on my opinion of what the question seemed to be asking. If I answered the question the OP was asking sufficiently, it shouldn't matter even if I interpreted the question in an illogical way. What matters is that OP better understands security/cryptography as a result of asking this question. After all, accepting an answer is about whether or not they now know what they wanted to know. It's not an award for the answer that interprets the question most logically. – guest Nov 18 '17 at 10:32
  • 1
    @guest Yepp, I accept what helped the most. The community can still upvote the other answer. I guess Smoke does not understand how this site works. – inf3rno Nov 18 '17 at 12:51
  • 2
    I think that was meant more as a burn than as an actual claim regarding the absurdity of having your answer not being the chosen one being taken as a "personal insult". Regardless, since the question is answered, we can all go home happy. – guest Nov 18 '17 at 14:52

I'm not sure what you mean by "streaming decryption". In cryptography, a symmetric cipher is either a block cipher or a stream cipher. It has nothing to do with "streaming data", but rather with how much is processed at once.

RSA and asymmetric cryptography

RSA is an asymmetric cipher. It is not actually designed to encrypt data, but rather encrypt a small random value which is to be used as a shared secret for a more traditional symmetric cipher. This is sometimes termed hybrid cryptography. RSA is very slow and very space-inefficient on its own.

Block ciphers

A block cipher can encrypt data in chunks of the block size of the cipher (128 bits for AES, for example). If the size of the plaintext to be encrypted is not exactly divisible by the block size, it needs to be padded. A block cipher is typically used with a "mode of operation", which provides additional security depending on how it is used, and sometimes authentication as well. Each mode should only be used for a specific purpose. Using a mode for the wrong purpose can be dangerous.

These ciphers work by applying multiple rounds of encryption to a single block of data with a given key. Changing any bit in the plaintext block results in every bit in the ciphertext block being randomized. All block ciphers work the way you describe, i.e. acting on individual chunks, one at a time.

An example of a block cipher is AES. It is not a stream cipher as you claim.

Stream ciphers

A stream cipher on the other hand can encrypt individual bits, one at a time. They are often also very fast. These ciphers work by encrypting each bit, one at a time. Changing one bit in the plaintext typically results in the corresponding bit in the ciphertext being flipped.

An example of a stream cipher is ChaCha20.

Block ciphers turned used as stream ciphers

Some modes of operation can make block ciphers act as stream ciphers. Typically this is done by having a mode of operation that creates a deterministic random data stream (such having a stream of plaintext blocks, each with incrementing numbers) which is then XORed with the data to be encrypted.

An example of a block cipher in a streaming mode is AES in CTR mode.

  • While this is a good overview of the differences of stream ciphers and block ciphers, this is not what OP is trying to ask, afais, and is not answering the question. – Tobi Nary Nov 18 '17 at 6:59
  • My bad. It sounded like he was confusing stream ciphers and block ciphers, which I tried to clear up. Your answer seems to imply he is talking about layering crypto. I didn't get that from the question, but I didn't perfectly understand the intention of the question, either. – guest Nov 18 '17 at 7:50
  • It‘s not about layering crypto but rather about decrypting in chunks rather than having to have the whole cipher text before one can start decrypting. Basically what all reasonable modes of operation support. OP just used a word (Streaming) that has a special meaning in crypto; OP is probably unaware of that and can thus probably not see where you’re aiming at. – Tobi Nary Nov 18 '17 at 7:53
  • Ah! So essentially he was referring to propagating modes like PCBC as streaming? That makes more sense. – guest Nov 18 '17 at 7:57
  • That is at least how I interpreted the question. – Tobi Nary Nov 18 '17 at 7:58

I am pretty sure you are not talking about stream ciphers (a method of deterministically generating a stream of pseudorandom bits which has arbitrary length). That is why I‘m not going into the differences between block ciphers, stream ciphers and how one can construct one from the other.

My reasoning is that you in fact say RSA had

support for streaming decryption

(which is wrong).

What I will focus on instead is a high level view on chunk/block size and the results of that, because that seems to be the point here.


RSA has a block size of at most the length of the key. That is because of how RSA is constructed. At a high level, there is some multiplication going on and then the rest of a division is the ciphertext; if you put too much information into this, the rest of that division will be - when decrypted - not the same (i.e. because you leave the RSA modulus Ring and used an invalid plain text).

To fix this problem and make RSA able to encrypt arbitrary data lengths, standardized rules are used to structure the plain text into chunks that each go through RSA and then combine them to a cipher text.

This is why you can partially decrypt an RSA cipher text: each of those chunks can be decrypted with (only) the knowledge of the previous one(s).

This has nothing to do with a stream cipher (where each bit can be decrypted as it comes it), but one can seem like streaming because 4096 bits are not much for a machine or a network today to buffer or receive.

Block Ciphers

From this high level perspective, block ciphers are comparable to RSA in this manner because - as the name suggests - they encrypt blocks of data. AES for example does this in 128bit blocks.

To enable block ciphers to encrypt larger amounts of data, so called a so called „mode of operation“ is used to standardize how blocks are put together.

For all modes I know of the top of my head, you only need blocks‘ plain texts from before the current block in the cipher text to decrypt a block in question.

Hence, with how I interpret your question for streaming possibilities, it should be theoretically possible to stream the input cipher text blocks through the decryption function and have it output the plain text as new cipher text blocks are received.


So, to be clear: what you are trying to do is already de-facto-standardized, it depends on the mode of operation used for the block cipher.

Additionally, neither RSA nor AES or any other (block) cipher or asymmetric cipher is designed with streaming in mind - and it doesn’t need to be, as they are just building blocks for a greater scheme, as you can see from the explanation above.

Yet, I wouldn’t generalize this to „this can be done with all ciphers“.

It is trivial to construct from either three options (stream cipher, block cipher, asymmetric cipher) a mode that puts the necessary information needed to decrypt the cipher text at the end of the cipher text, thus making it impossible to decrypt anything before the last bits of the cipher text are available.

  • 2
    Good answer overall, but: you say "AES128 does this in 128bit blocks", which may confuse people who don't know much about AES (which, incidentally, is a is a narrowed and formalized version of the Rijndael cipher). "AES128" (or "AES-128") refers to AES using a 128-bit key. The other standard sizes for AES are 192 and 256 bit keys. However, all AES variants, no matter the key size, use a 128-bit block size. – CBHacking Nov 18 '17 at 10:15
  • Fair point. I used AES128 because of the proximity to rijndael that was mentioned in the Q, but I see why that might be confusing. I will edit that:) – Tobi Nary Nov 18 '17 at 10:18
  • 1
    Addition: modes like AES-SIV (RFC5297) and AES-GCM-SIV (RFC draft) are not streamable, you have to buffer the full message for encryption and decryption and for AE-based decryption it is strongly recommended to not give data to the application before verification of the tag (usually at the end) succeeded. – SEJPM Nov 18 '17 at 15:32
  • @SEJPM There were bound to be auch modes. Thus „from the top of my head“;) – Tobi Nary Nov 18 '17 at 15:33
  • Not just auth modes, but propagating modes like PCBC can't be streamed without starting at the beginning. – guest Nov 18 '17 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.