The library 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, the 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 of 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 rememebering 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 were a recent question about Is it dangerous to encrypt lots of small files with the same key?. One can use the 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 part of the new and old version of the file may lose confidentiality. Therefore, for every update use a new nonce and encrypt the file again.