diff --git a/docs/secret.rst b/docs/secret.rst index 82387973797bfe6220f457e7c2abd5ad56584fee..797ecefa95d4083e76f7f64e5412e4556b5cf771 100644 --- a/docs/secret.rst +++ b/docs/secret.rst @@ -56,31 +56,28 @@ decrypt the data, or encrypt new data. Nonce ~~~~~ -The 24 bytes nonce (`Number used once <https://en.wikipedia.org/wiki/Cryptographic_nonce>`_) -given to :meth:`~nacl.secret.SecretBox.encrypt` and :meth:`~nacl.secret.SecretBox.decrypt` -must **NEVER** be reused for a particular key. Reusing the nonce means an -attacker will have enough information to recover your secret key and encrypt or -decrypt arbitrary messages. A nonce is not considered secret and may be freely -transmitted or stored in plaintext alongside the ciphertext. - -A nonce does not need to be random, nor does the method of generating them need -to be secret. A nonce could simply be a counter incremented with each message -encrypted. - -Both the sender and the receiver should record every nonce both that they've -used and they've received from the other. They should reject any message which -reuses a nonce and they should make absolutely sure never to reuse a nonce. It -is not enough to simply use a random value and hope that it's not being reused -(simply generating random values would open up the system to a -`Birthday Attack <https://en.wikipedia.org/wiki/Birthday_attack>`_). - -One good method of generating nonces is for each person to pick a unique prefix, -for example ``b"p1"`` and ``b"p2"``. When each person generates a nonce they -prefix it, so instead of ``nacl.utils.random(24)`` you'd do -``b"p1" + nacl.utils.random(22)``. This prefix serves as a guarantee that no -two messages from different people will inadvertently overlap nonces while in -transit. They should still record every nonce they've personally used and every -nonce they've received to prevent reuse or replays. +The 24-byte nonce (`Number used once <https://en.wikipedia.org/wiki/Cryptographic_nonce>`_) +given to :meth:`~nacl.secret.SecretBox.encrypt` and +:meth:`~nacl.secret.SecretBox.decrypt` must **NEVER** be reused for a +particular key. Reusing a nonce may give an attacker enough information to +decrypt or forge other messages. A nonce is not considered secret and may be +freely transmitted or stored in plaintext alongside the ciphertext. + +A nonce does not need to be random or unpredictable, nor does the method of +generating them need to be secret. A nonce could simply be a counter +incremented with each message encrypted, which can be useful in +connection-oriented protocols to reject duplicate messages ("replay +attacks"). A bidirectional connection could use the same key for both +directions, as long as their nonces never overlap (e.g. one direction always +sets the high bit to "1", the other always sets it to "0"). + +If you use a counter-based nonce along with a key that is persisted from one +session to another (e.g. saved to disk), you must store the counter along +with the key, to avoid accidental nonce reuse on the next session. For this +reason, many protocols derive a new key for each session, reset the counter +to zero with each new key, and never store the derived key or the counter. + +You can safely generate random nonces by calling ``nacl.utils.random(SecretBox.NONCE_SIZE)``. Reference