i try to use chacha20 encryption in my network software but i encounter a problem
if i encrypt 4 bytes data: 0x01 0x02 0x03 0x04
on server
and get the ciphertext: 0xd2 0xd3 0xc4 0xd5
, then send it to client
the client may receive <= 4bytes at a time
provided that client only recv 0xd2 0xd3
at first ,
it can decrypt data properly and get plaintext 0x01 0x02
but when client recv the last 2 bytes 0xc4 0xd5
it seems that the data can't be decrypt using the same nonce and key
so is there a way to solve the problem
adding length data as prefix before sending is a solution,but it's weird because i am using stream cipher.
ChaCha20 generates a stream, using the key and the nonce. Let
(S0, S1, S2, S3)
the first bytes of the stream, and(M0, M1, M2, M3)
the first 4 bytes of your message.The ciphertext will be computed as
(M0⊕S0, M1⊕S1, M2⊕S2, M3⊕S3)
. This is if you haveM0...M3
readily available.If you encrypt
(M0, M1)
then(M2, M3)
using the same key and nonce, you will end up with(M0⊕S0, M1⊕S1)
and(M2⊕S0, M3⊕S1)
. Which cannot be decrypted using(C0⊕S0, C1⊕S1, C2⊕S2, C3⊕S3)
.Even worse, since
S0
andS1
have been reused with different messages, an attacker can recover them knowing any message.The easiest thing to do in order to avoid this is to buffer the data until you reach the block size, and then encrypt the whole block, instead of trying to encrypt partial blocks.