The library also uses XChaCha20Poly1305
and that requires a nonce of 192-bit (24-byte). It is an extension of ChaCha20Poly1305
to increase the nonce size, ChaCha20 had 96-bit nonces. There is no standard for it, only a draft in ietf.org
The nonce is an acronym for 'number used once'. The crucial point is that one must never use the (Key, nonce) pair again. We call it nonce-misuse. If it occurs, confidentiality is lost as the attacker can use the crib-dragging technique to reveal the two plaintexts. There is even an automated approach to solve it:
Or for detailed examples see the answer to this question;
For 192-bit nonces, random nonce generation is safe, since as per birthday paradox you would need to encrypt $2^{96}$ messages under the same key to hit the same nonce again with 50% probability, so you should encrypt way less messages to ensure that this probability is negligible. Keep in mind that you need to use a good random number generator like /dev/urandom
. You can still use counter-based nonces if you want.
I am not sure what this value should be. Ideally, the user could recover this encrypted data with their key alone.
The nonce does not need to be secret and can be saved together with the file without being encrypted. This is not insecurity, only the key is secret. The nonce helps to use a key securely for more than once. It is secure as long as a (key, nonce) pair never occurs twice.
However, in order to decrypt any data, the nonce is also required.
That is completely normal since the decryption is the reverse of the encryption with the same key and nonce. XChaCha20Poly1305
generates a stream and we use it to x-or the plaintext. In order to regenerate the stream, we need to use the same inputs.
Hard-coding some nonce in the application feels odd, but if I randomly generate a nonce, the user will be required to remember this nonce along with their provided key in order to recover the encrypted data.
Hard-coding a nonce is not acceptable as then it would be used more than once. There is no problem with remembering the nonce, it is secure. Save it in a file like $$nonce\mathbin\|encryptedFile\|tag.$$
Note 1: The XChaCha20Poly1305
is an Authenticated Encryption, that will provide you confidentiality, integrity, and authentication if correctly used. Incorrect tags must not be ignored during the decryption. If the tag doesn't match, throw an error.
Encryption
$$(c,tag)= XChaCha20Poly1305Enc(key,nonce,message)$$
Decryption
$$(m|\perp) = XChaCha20Poly1305Dec(key,nonce,c)$$
where $\perp$ (\perp
) is the halt if the tag mismatch.
Note 2: There was a recent question about Is it dangerous to encrypt lots of small files with the same key?. One can use a similar idea to generate different keys for each file, too.
A final note: if you encrypt and update data multiple times with the same key and nonce this also can cause nonce-misuse and some parts of the new and old versions of the file may lose confidentiality. Therefore, for every update use a new nonce and encrypt the file again.