Score:2

ECDH between identical public keys

bd flag

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?

samuel-lucas6 avatar
bs flag
ECDH can be used for that use case; it normally involves doing a key exchange with an ephemeral key pair and storing the ephemeral public key with the file. Don't use `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.
Trafo avatar
bd flag
@samuel-lucas6 I would like to understand why not to use `crypto_box`. Especially because I meant `crypto_box_easy` with 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.
samuel-lucas6 avatar
bs flag
It's a common misconception that `crypto_box_easy` provides sender authentication. It [doesn't](https://github.com/jedisct1/libsodium/issues/586). Also see [RFC 7748 Section 7](https://www.rfc-editor.org/rfc/rfc7748#section-7). `crypto_box` uses XSalsa20 as it says [here](https://doc.libsodium.org/public-key_cryptography/authenticated_encryption#algorithm-details). 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 of `crypto_box` between two parties.
Trafo avatar
bd flag
@samuel-lucas6 I got it now your statement, that the key derivation function is the weakest link. It is all about entropy. Blake2B is allowing maximal 128-bit entropy, because of collisions. And this is fine, till we are in a post-quantum world. And I agree HKDF where no entropy will get lost has definitely a lot of advantages.
samuel-lucas6 avatar
bs flag
HSalsa20 is being used, not BLAKE2b. BLAKE2b can be used to create the equivalent of HKDF. All HKDF really does is an additional step to turn a shared secret (non-uniform) into a cryptographic key before using that uniform key to produce more keys. HMAC-SHA-2 in HKDF can be replaced with keyed BLAKE2b or HMAC-BLAKE2b. Technically, this additional step isn't required, but it should be slightly more secure, especially if a salt is used to add randomness.
Trafo avatar
bd flag
@samuel-lucas6 I hope last one. Because I misunderstood your statement. Because you said **libsodium is an excellent library; the key derivation API is the weakest link** What you meant was not Key Derivation API directly which is using Blake2B you meant key derivation inside of cryptobox? Does that mean the key derivation function provided by libsodium will do the same as HKDF and transform a non-uniform secret ECDH result to a cryptographic key before extracting more, which is highly recommended for ECDH? And I don't have many benefits of replacing Blake2b with HKDF-SHA-2?
samuel-lucas6 avatar
bs flag
Well it's quite complicated. The libsodium KDF is not widely used, unlike HKDF. It's not BLAKE2X, which is the 'official' BLAKE2 KDF, although that's basically not used at all. It also doesn't follow the extract-then-expand methodology of HKDF, so I don't think it achieves [KDF security](https://soatok.blog/2021/11/17/understanding-hkdf/), just PRF security. If I'm correct, that means you should technically hash a shared secret prior to using it as the key in the libsodium KDF. I explain how to do that hashing with the public keys in my answer.
Trafo avatar
bd flag
Thx for the info, helped me again a lot. Blake2X can be easily built out of Blake2B. They are not compatible because Blake2X needs some extra parameters for expanding the data. Blake2B personalized API is kind of the expand-part of HKDF, without having multiple steps, because it stops at the first and does not continue to append multiple random blocks. The extract-part is very often not needed, in case you have already a high entropy source, which the API of libsodium states out, why KDF security is not needed in that case. In case I don't have high entropy, I can hash it as you stated. Thx!
Score:1
ru flag

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.

fgrieu avatar
ng flag
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.
Daniel S avatar
ru flag
@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.
Score:1
bs flag

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:

  1. Use crypto_box_keypair to randomly generate an ephemeral key pair (ephemeralPrivateKey, ephemeralPublicKey).
  2. Use crypto_scalarmult to perform a key exchange between your privateKey and ephemeralPublicKey. This produces sharedSecret.
  3. Erase the ephemeralPrivateKey (e.g. using sodium_memzero or the equivalent in your programming language).
  4. Derive an encryption key for XChaCha20-Poly1305 using crypto_generichash, with sharedSecret || your publicKey || ephemeralPublicKey as the message.
  5. Encrypt the plaintext using XChaCha20-Poly1305 with the above key and a randomly generated nonce.
  6. Prepend ephemeralPublicKey and 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

Trafo avatar
bd flag
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?
samuel-lucas6 avatar
bs flag
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](https://neilmadden.blog/2018/11/26/public-key-authenticated-encryption-and-why-you-want-it-part-ii/) blog post for an explanation.
samuel-lucas6 avatar
bs flag
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.
Trafo avatar
bd flag
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.
samuel-lucas6 avatar
bs flag
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.
Trafo avatar
bd flag
Thx 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?
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.