Reputation: 64
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.
Upvotes: 0
Views: 509
Reputation: 93948
Instead of restarting the ChaCha20 cipher instance (or, more generically, context) you should keep it alive.
Most cryptographic API's will allow you to perform piecemeal encryption / decryption. That usually means calling an update
method for the first part and second part, generally followed by a final
method when the end of the plaintext / ciphertext is detected. Depending on the API you should expect output for each of these methods.
Only if your API doesn't allow you to handle the stream correctly then you should aggregate the ciphertext and perform the decryption on the full ciphertext.
Upvotes: 3
Reputation: 1501
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 have M0...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
and S1
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.
Upvotes: 1