1

I am currently working with a symmetric algorithm which requires a nonce for encryption, and logically for decryption as well.

However, I am a bit confused about how I would go and synchronize the nonce on both clients.

Let's say my nonce is starting at 0 and is hardcoded on both sides.

I would then encrypt my data, and increase the nonce to avoid leakage through reuse. The encrypted value will be sent to my client, which decrypts the data and increases the nonce as well. Now both parties have a nonce of 1, ready for the next encryption/decryption cycle.

This works well, as long as there are no unexpected things happening.

Let's say the server is now encrypting with a nonce of 5. It increases the nonce to 6 afterwards, but somehow the connection failed, and the value is never transmitted. The other participant does not receive an update and his nonce will stay at 5.

The next time we encrypt something, the encryptor now uses the nonce 6, increases it and sends the value. The decryptor side however is still at a nonce of 5 and the decryption will therefore fail.

How do I get out of this cycle? How can I securely synchronize the nonces, so I can avoid complete failure if the connection will fail at least once? Is it secure to just transmit the current nonce with every data package? Are there any other approaches?

Sossenbinder
  • 135
  • 5
  • 2
    Do you absolutely need the nonce? Can your algorithm depend on something else? Whether you can transmit the nonce with every data package depends on the kind of encryption algorithm – Limit Jul 06 '17 at 13:28
  • To expand on what Limit is saying: Requiring a new nonce every data package means that a missing package will prevent future communications. As an alternative, look at TLS or SSH, both of them use symmetric encryption to transfer data securely. – ztk Jul 06 '17 at 20:00

1 Answers1

2

The simplest solution is to just send the nonce along with each message. There is no requirement that the nonce be secret, and in fact, in the protocol you're describing an attacker would likely be able to guess the nonces anyway. If you just transmit the nonce then there's no need for synchronization—all the server needs to do is guarantee that it won't reuse a nonce.

Note that don't need to literally send the full nonce along—any value that you can send that can be used to reconstruct the full nonce will do. For example, if you're using a counter for the nonce, it's ok to use a compact, variable length encoding of the counter.

There are other tricks you might want to consider to reduce the need for synchronization between the two participants. For example, if the communication is full-duplex (i.e., both participants alternate roles as sender and recipient), you might want to either:

  1. Use separate keys for each direction of the communication—Alice uses key #1 to encrypt her messages to Bob, and Bob uses key #2 to encrypt his messages to Alice. That way if either mistakenly uses the same nonce as the other does, there's no problem because of the use of different keys.
  2. Make the parties use distinct subsets of the nonce space. For example, the server might use only even-numbered counter values when it encrypts messages, and the client odd-valued ones only.

These additional suggestions share a theme with your question: reliance on synchronization is risky. Ideally you want make sure that the participants in the protocol can act safely even if they don't know their counterparts' state. Or even worse, you want them to act securely even if their counterpart is in fact an adversary.

Luis Casillas
  • 10,181
  • 2
  • 27
  • 42