3

I have read that stream ciphers can be used to encrypt messages/streams of arbitrary length (cf. the description of the stream cipher tag). However, there are stream ciphers that create a keystream of fixed length and XORs message and keystream bit by bit.

Therefore, I wonder, what happens if the message length is longer than the length of the keystream ? Is the keystream applied repeatedly to the remaining parts of the message in this case ?

user120513
  • 175
  • 5
  • "there are stream ciphers that create a keystream of fixed length", which? Can you give some examples? – mikeazo Aug 15 '17 at 16:48
  • 1
    In ChaCha20 the keystream has a maximal length of 2^70 bytes (which is quite large, of course). – user120513 Aug 15 '17 at 17:14
  • If you can encrypt that much data, you have much more to worry about than the cipher. That said, the best thing to do would be to switch keys every once in a while. – mikeazo Aug 15 '17 at 17:17

1 Answers1

6

TL,DR: “arbitrary length” primarily means “the length doesn't have to be a multiple of a certain size”.

I have read that stream ciphers can be used to encrypt messages/streams of arbitrary length (cf. the description of the stream cipher tag).

That's generally the case, except that most stream ciphers have a maximum length. The maximum length is typically far larger than any practical message, so in practice stream ciphers can encrypt messages of arbitrary length.

The important thing about the “arbitrary length” of the message for stream ciphers is that you can stop the stream at any point. This is unlike block cipher modes, which can only encrypt a message whose length is a multiple of the size of a block. To encrypt a message with a block cipher, you need both a block cipher mode (to reach lengths larger than one block) and a padding mode (to cope with the last block, which in general is only partially filled).

For example, AES is a block cipher with a 16-byte block size. CBC is a block cipher mode (i.e. a way to turn a way to encrypt a fixed-size block into a way to encrypt a list of blocks). You can encrypt a 32-byte message with AES-CBC by running CBC for two blocks, but you can't encrypt a 31-byte message, because this isn't a whole number of blocks. You need to additionally specify a padding mode, e.g. PKCS#7 padding. You can encrypt a message of arbitrary length (in bytes — and again, up to a very large maximum) with AES-CBC-PKCS7 — first pad the message to 32 bytes with the PKCS#7 padding algorithm, then apply CBC for two blocks. In contrast, a stream cipher can encrypt a 31-byte message simply by calculating the cipherstream for 31 bytes. For example, to encrypt a 31-byte message with AES-CTR, you simply calculate 31 bytes of cipherstream and xor that with the message. Because CTR builds a stream cipher on top of a block cipher, calculating the cipherstream involves calculating two blocks (32 bytes) of ciphertext and discarding the last byte.

Padding is a reason to prefer stream ciphers to block ciphers. Padding looks simple, but it's actually subtle. In particular, bad treatment of padding on the decryption side can lead to padding oracle attacks. That being said, if the block cipher is used in a properly designed authenticated encryption algorithm, only the designer of the authenticated encryption algorithm needs to worry about this, not the end-user.

However, there are stream ciphers that create a keystream of fixed length and XORs message and keystream bit by bit.

If the keystream is of fixed length, then it's a one-time pad, not a stream cipher. That's a matter of terminology.

Therefore, I wonder, what happens if the message length is longer than the length of the keystream ?

Then you need a more complex protocol, with different keys for different parts of the message (i.e. key renewal). But in practice that basically never happens — if you have that much text to encrypt, it's almost always already split into separate messages.

Is the keystream applied repeatedly to the remaining parts of the message in this case ?

Absolutely not! Applying the same keystream more than once is very insecure. It's a two-time pad and that can leak the whole message.

  • instead of changing keys, you could also generate another nonce – Ella Rose Aug 15 '17 at 17:33
  • @user120513 Yes (I meant to write “block cipher mode”, actually). Thanks, fixed. – Gilles 'SO- stop being evil' Aug 15 '17 at 17:53
  • @Ella: May I ask which stream cipher you have in mind ? – user120513 Aug 15 '17 at 17:58
  • @user120513 None in particular, just any stream cipher that uses a nonce. Which is pretty much all of them other then RC4. – Ella Rose Aug 15 '17 at 19:08
  • *"Padding is a reason to prefer stream ciphers to block ciphers." What's a reason to prefer block ciphers over stream ciphers? Would be nice if you could explain that since my first reaction whenever I read "block cipher" is "why does anyone even do this"... – user541686 Aug 15 '17 at 19:25
  • @Mehrdad Sorry, cipher design is way above my grade. I (as a developer of programs that use crypto) use block ciphers because AES is the de facto standard and it's a block cipher (and I'm too young for it, but before AES there was DES, also a block cipher). Until recently the only widespread “direct” stream cipher was RC4 and it had long-known weaknesses. – Gilles 'SO- stop being evil' Aug 15 '17 at 20:17
  • Would it be fair to call stream ciphers "Block ciphers with a block size of 1 byte", then? – Nathan Merrill Aug 15 '17 at 20:23
  • @Gilles: Haha okay thanks, that's still good info. :) – user541686 Aug 15 '17 at 20:30
  • @NathanMerrill No. Stream ciphers act in a specific way: ciphertext = keystream xor plaintext. There isn't even anything special about bytes when it comes to stream ciphers: a stream cipher can encrypt a message of an arbitrary length in bits. I'll let you work out what a block cipher with a size of 1 bit looks like; it's totally useless for crypto. (even 1 byte is too short for a block size but it's less obvious.) – Gilles 'SO- stop being evil' Aug 15 '17 at 20:53