Server and client have a pre-shared key K. Assuming that that pre-shared key is
ID: 651889 • Letter: S
Question
Server and client have a pre-shared key K. Assuming that that pre-shared key is safe, so nobody other than server/client can encrypt/decrypt.
Client sends a nonce N to server, server then sends back message M in encrypted form AES_CBC_Encrypt(M+N, K, IV) to client. So client can verify if there is a replay attack trying to send an expired message.
Is it necessary for client to send N in encrypted form AES_CBC_Encrypt(N, K, IV) or it is OK to just send N in clear.
M and N are 16-byte array, M+N means concatenation of M and N).
Explanation / Answer
If your nonce is 16 bytes, and your message pre-nonce is a multiple of 16 bytes (i.e. no padding is needed), sending the nonce in the clear opens you up to replay-ish attacks. Specifically, if an attacker captures one exchange with nonce N and response R (with b blocks R1 through Rb), and then impersonates the server and the client sends them N? as nonce, they can create a new message with the correct nonce at the cost of scrambling the last block of M (by XORing the second-last block of R with N?N?). How this affects your system depends on the specific system, but this is generally not something you want to be possible.
The proper way to mitigate this isn't to send N encrypted: it's to use authentication on the server's response. The client will already refuse a message that has a previously used nonce; it will also refuse a message that doesn't have the correct nonce value. That means that an attacker already can't do a straight replay attack, because a straight replay will be rejected. However, you should still worry about an attacker maliciously tweaking the message (that thing where if they know the contents of one block, they can change them at the cost of scrambling the previous one? That's true for all your blocks, and they can do it on the first block without scrambling any other blocks at all.) On the other hand, with a proper message authentication code, you can prevent any attacker who doesn't know the key from feasibly forging any message from the server; properly done authentication means that the only messages an attacker could send are exact replays, so if you can throw those out they can't do anything.
So the correct response is "use authentication, preferably with an AEAD mode like GCM, CCM, or EAX." (AEAD combines encryption and authentication in a secure way; it's fairly easy to screw up if trying it yourself). If you can't use AEAD, share a second key to use for a MAC algorithm and then use that MAC on the ciphertext to authenticate it (and do that before decrypting the ciphertext). Then you don't need to worry about encrypting N or not, because the attacker can only pull off an exact replay and an exact replay is blocked by your challenge-response system.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.