We are using libsodium and regarding exchanging secrets we would like to use the so-called crypto_box (https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption). Under the hood, ECDH is used. The problem is that it can be possible as well, that I encrypt this secret by myself. In that case, Alice and Bob would be the same person and the public keys will not differ. Is that a security problem, because DH was not designed for this kind of use case?
2 Answers
There's an elegant argument that the computational Diffie-Hellman problem with repeated keys is no harder than the generic computational Diffie-Hellman problem.
We write $\mathrm{CDH}(G,aG,bG)$ for the generic computational Diffie-Hellman problem of computing $abG$ given $g$, $aG$ and $bG$ and $\mathrm{rCDH}(G,aG)$ for the repeated key computational Diffie-Hellman problem of computing $a^2G$ given $G$ and $aG$. Suppose that we have an advantageous way of solving $\mathrm{rCDH}$ and a $\mathrm{CDH}$ instance $\mathrm{CDH}(G,A,B)$. I can compute $A+B=(a+b)G$ and $A-B=(a-b)G$ and call my $\mathrm{rCDH}$ solver twice to get $\mathrm{rCDH}(G,A+B)=(a^2+2ab+b^2)G$ and $\mathrm{rCDH}(G,A-B)=(a^2-2ab+b^2)G$. Subtracting these two return values gives me the point $4abG$ and scalar multiplying by $4^{-1}\mod \ell$ where $\ell$ is the group order gives $abG$ and thus solves the $\mathrm{CDH}(G,A,B)$ problem.
- 23,716
- 1
- 29
- 67
-
Subtitle [edited]: this supports that crypto_box is not weakened when the two parties use the same public/private key pair, but is not quite a proof of that. – fgrieu Jan 26 '23 at 13:22
-
1@fgrieu I've just nerd-sniped myself with this one. Any security properties of crypto_box that depend on CDH are not weakened, but OTOH I can't construct a proof that $rDDH\Rightarrow DDH$. If there are any security properties that depend on DDH, I'm not sure if there's an additional hardness assumption in the repeated case. – Daniel S Jan 26 '23 at 13:29
I would never recommend using crypto_box as it has a number of limitations:
- It doesn't provide sender authentication, only message authentication, because the public keys are not included in the key derivation, as recommended in RFC 7748.
- It uses HSalsa20 for key derivation. Firstly, this causes the above problem, which was also an issue I reported in Monocypher. Secondly, HSalsa20/HChaCha20 should really be supplied a uniformly random key, whereas shared secrets are not.
- It uses XSalsa20-Poly1305 instead of XChaCha20-Poly1305. This isn't a security problem as both are secure, but (X)ChaCha20 is far more popular now, and ChaCha20 is slightly more efficient and has better diffusion.
Instead, you can do the following:
- Use
crypto_box_keypairto randomly generate an ephemeral key pair(ephemeralPrivateKey, ephemeralPublicKey). - Use
crypto_scalarmultto perform a key exchange betweenyour privateKeyandephemeralPublicKey. This producessharedSecret. - Erase the
ephemeralPrivateKey(e.g. usingsodium_memzeroor the equivalent in your programming language). - Derive an encryption key for XChaCha20-Poly1305 using
crypto_generichash, withsharedSecret || your publicKey || ephemeralPublicKeyas the message. - Encrypt the plaintext using XChaCha20-Poly1305 with the above key and a randomly generated nonce.
- Prepend
ephemeralPublicKeyand the nonce to the ciphertext.
If the crypto_kx API is accessible, that does key derivation similarly for you, just use crypto_kx_client_session_keys to derive one key rather than two. There's no need to use crypto_kx_server_session_keys because there's no second party involved.
This provides sender authentication, uses a hash function for key derivation (HKDF or the personalised BLAKE2b KDF API could be used instead), derives a unique key each time, and uses a newer AEAD.
Documentation
- 1,783
- 7
- 17
-
Thx for the answer. The alternative will still not provide any sender authentication, because of the ephemeral key? It just uses better algorithms? And in my use case, a more common scenario is that Alice and Bob are different. That sender and receiver could be the same, is just an edge case. In that case, I can skip the ephemeral key and use the sender key. And in case the sender and receiver are the same it seems like I can use the same public key as well, because of the other answer. If I would like to have sender authentication, I should use on top public key signature? – Trafo Jan 26 '23 at 14:50
-
This does provide sender authentication because the public keys are included in the key derivation. It doesn't matter that the public key is ephemeral. Doing Alice and Bob gets far more complicated because you should still be using ephemeral keys. See this blog post for an explanation. – samuel-lucas6 Jan 26 '23 at 15:27
-
I should also add that just performing the key exchange with your own public key would result in the same shared secret and key each time unless you're performing some salting. – samuel-lucas6 Jan 26 '23 at 15:34
-
But given the same params for scalarmut would that not be anyways the case? Even in case, both public keys differ? I guess that is the argument for using ephemeral keys. – Trafo Jan 26 '23 at 15:51
-
The same parameters will produce the same shared secret. Not sure what you mean by 'both public keys differ'. Using a different or ephemeral public key anywhere will result in a different shared secret and hence a different key. If you look at the blog post I linked (technically 3 posts), it will explain more important reasons for using ephemeral keys. It's up to you how secure you want things to be/what properties you're looking for. I suggest you search for answers to further questions and ask a new question if you can't find an answer anywhere. – samuel-lucas6 Jan 26 '23 at 16:06
-
1Thx very much, your posted blog post helped a lot. I understood now the struggles and why for example my naive thought to just encrypt and sign asymmetrically is less straightforward than I expected and why the crypto box has its flaws. Will use HKDF instead of crypto_generichash. Regarding the blog post and your suggested way, I see that they use two times ECDH (ephemeral-static and static-static) which you skipped because you assumed that Alice and Bob are the same. As well KCI attack seems to be irrelevant with ephemeral ECDH? – Trafo Jan 26 '23 at 16:41
crypto_box. There are a number of problems with it. It doesn't provide sender authentication, it uses HSalsa20 instead of a proper KDF (e.g. HKDF), it uses XSalsa20 instead of XChaCha20, and both parties can decrypt messages, which you usually want to prevent. – samuel-lucas6 Jan 26 '23 at 12:38crypto_box. Especially because I meantcrypto_box_easywith authentication (https://doc.libsodium.org/public-key_cryptography/authenticated_encryption). And there the sender is authenticated. Sadly I am stuck using libsodium, even though I share your concerns regarding a proper key derivation function. But from my knowledge, they embrace everywhere using XChaCha20, where do you get the information, and what are the alternatives? That both parties can decrypt the message is fine because the sender knows the message anyways. – Trafo Jan 26 '23 at 13:45crypto_box_easyprovides sender authentication. It doesn't. Also see RFC 7748 Section 7.crypto_boxuses XSalsa20 as it says here. libsodium is an excellent library; the key derivation API is the weakest link but HKDF is being added. I know both parties is fine in this case but not for generic uses ofcrypto_boxbetween two parties. – samuel-lucas6 Jan 26 '23 at 13:52