/dev/posts/

Introduction to the Diffie-Hellman key exchange

Published:

Updated:

The Diffie-Hellman (DH) key exchange (and variants thereof) is widely used in many protocols (such as TLS, SSH, IKE (IPSec), Signal, etc.) to bootstrap some symmetric key material which may then be used to secure communication channel between two parties. This introduction focuses on the different ways the DH key exchange is used in practice in several protocols (especially TLS) and the impact of these different approaches on the security. This is intended as a prelude for the upcoming next episodes about how TLS works.

Prerequisites: public key vs. private key vs. secret key key, encryption, MAC, digital signature, cryptographic hash.

Concepts introduced: Diffie-Hellman key exchange, anonymous vs. authenticated Diffie-Hellman key exchange, ephemeral vs. static Diffie-Hellman key pairs/exchange, triple Diffie-Hellman key exchange (3DH), forward secrecy, key compromise impersonation (KCI), identity misbinding attack, unknown key-share attack.

Update 2024-11-12: add some notes about using RSA-based key exchange.

After a quick overview, we will present the unauthenticated DH key exchange. The downside of the unauthenticated DH key exchange is that the parties have no assurance that they are actually communicating with the intended party: this approach only protects against passive eavesdroppers but not against active attackers. and it is therefore usually desirable to authenticate at least one participant. We will see several approaches to integrating some authentication (for either or both parties) in the key exchange:

Warning: about not rolling one's own crypto

I'm not an expert in cryptography. This post is not supposed to teach you how to implement secure cryptographic protocols. There are a lof of missing bits, details and caveats (how to choose your parameters and keys, how to verify the parameters, how to avoid side-channel attacks, etc.).

Do not roll your own crypto (for anything serious, unless you really know what you are doing). Use a reputed implementation of a well-known protocol (eg. TLS) if possible.

Table of content

Overview

Motivation

Let us assume that Alice and Bob want to communicate over the network. They would like to protecte themselves from eavesdroppers (Eve[1]) listening to their communications (confidentiality) and active attackers (Mallory[2]) tampering with their communications (data integrity). They could use encryption and Message Authentication Codes (MACs) in order to provide confidentiality and data integrity[3] respectively. In order to do that, they need to agree on some shared keys to use (for the encryption and/or MAC).

Obviously, Alice cannot simply send these shared keys to Bob in clear text over the network: these secrets keys would not be secret at all. An attacker could eavesdrop them and use them to decrypt the communications or tamper with them. Instead, Alice and Bob would need a method to agree on some shared keys without sending these keys (or any other informations which could be used to compute them) in clear text over the network.

Summary

The Diffie-Hellman key agreement is a method for two parties to agree on a shared secret without revealing this shared secret to eavesdroppers.

How? The two parties exchange Diffie-Hellman public keys and each party then uses its own Diffie-Hellman private key with the other party Diffie-Hellman public key to compute the same shared secret (the Diffie-Hellman shared secret). This shared secret is not revealed to eavesdroppers because even though the eavesdropper can observe the DH public keys, he does not know any of the two DH private keys: he therefore cannot compute the DH shared secret.

The following diagram gives an idea about how this works. Some details on these computations are given in appendix.

Generator g;
              Alice's private key ka;
              Alice's public key Ka = ka.g;
              Bob's private key kb;
              Bob's public key Kb = kb.g;
              DH shared secret: z = ka.kb.g = kb.ka.kg
Graphical representation of the DH shared secret computation

Why? The two parties can use this shared secret to secure some communication by deriving[4] some symmetric key material from the shared secret.

Note: derived key material

The key material derived from the DH shared secret would typically include:

  • two encryption secret keys (one for each direction i.e., Alice → Bob and Bob → Alice) to encrypt the messages (confidentiality);
  • two MAC secret keys (one for each direction) to authenticate the messages unless the cipher is an authenticated encryption (AE) mechanism (which already provides data authentication);
  • initialization vectors (IV), if needed.

You must not use the same key for different purposes. Instead, you must derive different keys for different purposes.

Note: Key derivation function

You must not use the Diffie-Hellman secret directly as key material (shared secret key, initialization vector):

  • It does not have the correct size.
  • More importantly, the Diffie-Hellman secret is not uniformly-distributed which makes it not suitable as a shared secret key. A key derivation function transforms it into something which is uniformly-distributed and can be used as shared secret key.

Instead, you must derive the key material from from the Diffie-Hellman secret using a key derivation function (KDF):

key_materiel = KDF(z)

For example,

Note: including context in the key derivation

In practice, you will want to bind the derived shared secret to the usage context as well:

key_materiel = KDF(z, some_context)

See for example:

Examples of usage

Many protocols use the Diffie-Hellman key exchange:

Note: FFDH and ECDH

The DH key agreement can be done using different types of mathematical objects (groups). For example,

  • Finite Field Diffie-Hellman (FFDH) uses finite fields;
  • Elliptic-Curve Diffie-Hellman (ECDH) uses elliptic curves.

Everything discussed here applies to both FFDH and ECDH.

The original/classical Diffie-Hellman formulation is FFDH. The term “DH” is often used to refer to FFDH as opposed to ECDH. For example, in TLS v1.2 and below the TLS_DH(E)_* cipher suites use FFDH whereas the TLS_ECDH(E)_* cipher suites use ECDH.

Unauthenticated Diffie-Hellman key exchange

The unauthenticated (anonymous) Diffie-Hellman key exchange uses ephemeral DH key pairs for each party: each party generates a new Diffie-Hellman (public/private) key pair for each Diffie-Hellman key exchange. This is called ephemeral-ephemeral Diffie-Hellman.

Note: static vs. ephemeral Diffie-Hellman key

Ephemeral DH key: when the party generates a new DH key pair for each key exchange.

Static DH key: when the party reuses the same DH key pair for all key exchanges.

Ephemeral-ephemeral DH (DHE): both parties use ephemeral DH key pairs.

Ephemeral-static DH (DHES): one party uses ephemeral DH key pairs and the other party a static DH key pair.

Static-static DH: each party uses its (own) static DH key pair.

Unauthenticated ephemeral-ephemeral Diffie-Hellman sequence diagram
Relation between the keys in the Diffie-Hellman key exchange

Explanation:

  1. each party generates a fresh (ephemeral) DH key pair;
  2. the two parties exchange their ephemeral DH public keys;
  3. each party uses its ephemeral DH private key and the other party DH public key to compute the same shared secret (the DH shared secret);
  4. this shared secret can be used to derive[4:1] key material in order to establish a secure communication channel.

Each party can compute the same shared secret using its private DH key and the other party public DH key:

shared_secret_between_alice_and_bob = DH(alice_private_key, bob_public_key)
                                    = DH(bob_private_key, alice_public_key)

A passive attacker, only knows the DH public keys but not the DH private keys: he cannot compute the DH shared secret and the key material.

Note: key confirmation

It is often necessary to include some key confirmation mechanism after the key agreement. See for example, the Finished messages in TLS v1.2 and v1.3.

Warning: vulnerable to active attack (unauthenticated)

One major downside of using an unauthenticated DH key exchange is that it is vulnerable to active attacks. As the exchange is not authenticated, one participant cannot be sure that the party he has been conducting a DH key agreement with is the one he is really intending to communicate with. By intercepting the key exchange, an active attacker may impersonate one party, intercept the communications, etc.

Active attack on unauthenticated Diffie-Hellman key exchange (sequence diagram)

In the following sections, we will cover how to authenticate a Diffie-Hellman key exchange using some long-term secret. This may be a static DH private key, a signing private key, a pre-shared key (PSK) or a passphrase.

Warning: don't use encryption without message authentication

You really want to use some form of message authentication in addition to encryption. This can be done either by using an AEAD (which already integrates message authentication in addition to encryption) or by including a MAC in addition to the encryption scheme you are using.

Example: usage in TLS v1.2

The anonymous TLS cipher suites use this approach. These are the cipher suites containing DH_anon or ECDH_anon (such as TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 or TLS_ECDH_anon_WITH_AES_128_CBC_SHA). The DH public keys are exchanged in the ServerKeyExchange and ClientKeyExchange messages.

The server is not authenticated when using these cipher suites.

Example: usage for opportunistic encryption in Wifi (OWE)

Wifi OWE (Opportunistic Wireless Encryption) uses an unauthenticated Diffie-Hellman key exchange to provide opportunistic encryption (protection against passive attacks) to open Wifi networks. OWE is designed to be used as a (more secure) replacement for unencrypted open Wifi.

In OWE, the station and the access point (AP) exchange ephemeral DH public keys in the 802.11 association request and association response messages respectively. They then derive key material from the resulting DH shared secret.

Authenticating the Diffie-Hellman key exchange using a static Diffie-Hellman key

Vulnerable one-way authentication using ephemeral-static Diffie-Hellman key exchange

A party (here Bob) can authenticate itself by using a static DH key pair bound to its identity.

Note: key distribution

For this to work, Alice somehow need to learn Bob's (static) DH public key. This may for example be:

  • through prior out-of-band provisioning;
  • through a certificate issued by a trusted certificate authority (CA);
  • using trust-on-first-use (TOFU), aka leap-of-faith.

If only one party is authenticated this way, the other party uses an ephemeral DH key pair: this is ephemeral-static Diffie-Hellman (DHES). If each party uses a (different) static DH key pair, this is static-static Diffie-Hellman (discussed below).

Ephemeral-static Diffie-Hellman key exchange (DHES) sequence diagram, vulnerable to replay attacks

Warning: lack of forward secrecy

If an attacker manages to get the static DH private key of one party, he can compute the DH shared secrets of all key exchanges which were using that static DH private key and decrypt the associated communications: static DH key exchanges do not provide forward secrecy with respect to the static DH private key.

This is why the usage of static DH key exchanges is now discouraged in TLS. Static DH key exchanges have been completely removed in TLS v1.3.

Replay Attack on static Diffie-Hellman key exchange

In the previous diagram, an attacker could make a replay attack on the party using the static DH key pair.

Replay attack on static Diffie-Hellman key exchange (sequence diagram)

This can be fixed by having this party send a random nonce and including this nonce to derive the key material.

Protection against replay attack on static-ephemeral Diffie-Hellman key exchange (sequence diagram)

Example: usage of static Diffie-Hellman keys in TLS v1.2

The TLS DH_DSS, DH_RSA, ECDH_ECDSA and ECDH_RSA key exchange methods (for example in TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA) use this approach for authenticating the server.

  1. the client and the server exchange random nonces in the ClientHello and ServerHello messages;
  2. the client and server exchange DH public keys in the ServerKeyExchange;
  3. they then derive a master secret from the random nonces and the DH shared secret.

TLS client authentication uses this approach as well when used with the rsa_fixed_dh, dss_fixed_dh, ECDSA_fixed_ECDH, RSA_fixed_ECDH certiticate types.

Using either of these method for authentication do not provide forward secrecy with respect to the static DH private key.

When both the client and server key are static, we have static-static Diffie-Hellman (see below).

Mutual authentication using static-static Diffie-Hellman key exchange

If each party uses a static a DH key pair, we get static-static Diffie-Hellman. In this case, the DH shared secret is always the same between the two parties. However, we don't want to reuse the same key material as the result of different key exchanges between the same pair of parties. In order prevent this, the parties can exchange nonces; then, they derive the key material from the DH shared secret and the nonces.

Static-static Diffie-Hellman key exchange sequence diagram

Warning: lack of forward secrecy

This does not provide forward secrecy with respect to any of the static DH private keys. If an attacker compromises any of the static DH private keys, she can then use this key to decrypt previous communications which were using that key.

Warning: key compromise impersonation (KCI)

In all these key exchange authentication methods, Alice authenticates herself using some authentication secret (either a static DH private key, a signing private key, a PSK or a passphrase). If an attacker manages to obtain Alice's authentication secret, this attacker can impersonate Alice.

In static-static DH[5], if the attacker manages to get Alice's private DH key, he can in addition impersonate anyone else when they are talking to Alice. This vulnerability is called Key Compromise Impersonation (KCI).

Key Compromise Impersonation in static-static Diffie-Hellman

See KCI Attacks against TLS for a practical application in TLS.

Mutual authentication using a triple Diffie-Hellman

Another solution to provide mutual authentication is to use a triple Diffie-Hellman (3DH)[6] key agreement. Each participant uses both a static DH key pair and an ephemeral DH key pair. They combine the DH shared secrets resulting from three DH key agreements:

Triple Diffie-Hellman (3DH) sequence diagram

Note: not vulnerable to KCI with respect to the static DH key pairs

An attacker having access to Alice's private static DH key cannot use it to compute the DH shared secret resulting from Alice ephemeral DH key pair and Bob static DH key pair. Therefore, this approach is not vulnerable to KCI with respect to the party static DH private key.

Example: X3DH, Signal, etc.

The Extended Triple Diffie-Hellman (X3DH) is an extensions of this approach. X3DH is used by the Signal protocol. The Signal protocol is used by Signal, What's App, etc.

Authenticating Diffie-Hellman key exchange using digital signature

Instead of using static DH key pairs, we can use digital signatures to authenticate the DH key exchange.

Badly authenticated Diffie-Hellman key exchange using digital signatures

One simple (but broken) solution would be for each party to sign either its own ephemeral DH public key or the two DH public keys.

Generator g;
              Alice's private key ka;
              Alice's public key Ka = ka.g;
              Bob's private key kb;
              Bob's public key Kb = kb.g;
              DH shared secret: z = ka.kb.g = kb.ka.kg
Badly authenticated Diffie-Hellman (BADH) sequence diagram

Note: freshness

In this diagram, each party signs both its own ephemeral DH public key (for authentication) and the other party ephemeral DH public key (for freshness). Including the other party ephemeral DH public key (or nonce contributed by the party) guarantees the freshness of the signature to the other party.

However, this approach is vulnerable to unknown key-share attack (alsa known as identity misbinding attacks). If Alice tries to established a mutually authenticated communications with Charlie and if Charlie is malicious (for example because it has been compromised), Charlie can trick Alice into establishing a communication with Bob instead:

Identity misbinding attack on a badly authenticated key exchange (sequence diagram)

This attack is possible because the attacker (Charlie) is able to manipulate the handshake messages without being detected.

Better authenticated Diffie-Hellman key exchange using digital signatures

Several approaches can be used to prevent this type of manipulations from getting unnoticed:

Authenticated key exchange using SIGMA (sequence diagram)

Example: usage in TLS v1.2 for server authentication

In TLS v1.2, the server authenticates itself using digital signatures when using the TLS_(EC)DHE_* cipher suites (for example TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256):

  1. the ServerKeyExchange message contains a signature of the server ephemeral DH public key the server and client nonces;
  2. the server Finished message contains a MAC of the previous messages.

Example: usage in TLS v1.2 for client authentication

In TLS v1.2, the client authenticates itself using digital signature when it uses the rsa_sign, dss_sign or ecdsa_sign certificate type:

  1. the client CertificateVerify message contains a signature of previous handshake messages;
  2. the client Finished message contains a MAC of previous handshake messages.

Example: usage in TLS v1.3

In TLS v1.3 (without PSK), both client and server authentication use a digital signature:

  1. CertificateVerify message contains a signature of the hash of the previous handshake messages;
  2. the Finished message contains a MAC of previous handshake messages.

Note: forward secrecy

This approach provides forward secrecy (with respect to the signing private keys). By getting access to one party's signing private key, an attacker could of course impersonate this party in subsequent key exchanges. However, having the signing private key would not enable the attacker to recover the DH shared secrets (and the key materials) of previous key exchanges which were authenticated using that key.

Key pair reuse

In the protocol as described in the previous diagram, the peers must not reuse the ephemeral Diffie-Hellman key pairs (each Diffie-Hellman ephemeral key pair must be used only once). If Alice reuses a Diffie-Hellman key pair, an man-in-the-middle might replay the previous messages originating from Bob as described in the following diagram (same attack previously described in the context ot a static Diffie Hellman key echange).

Replay attack if a peer reuses an ephemeral key pair if the previous protocol

Because Alice reused the same Diffie-Hellman key pair and did not contribute another one-time contribution to the key exchange:

If the peers exchange nonces in addition to the ephemeral Diffie-Hellman public keys (and if these nonces are integrated in the key derivation and signatures), reusing the Diffie-Hellman key pair would not completely compromise the security of the key exchange.

Authenticated Diffie-Hellman key exchange as used in TLS 1.3

Example: TLS

This is for example the case in TLS, where the peers exchange nonces (in the ClientHello and ServerHello messages). These nonces are integrated in the key derivation, signatures and key confirmation.

Warning: on the ephemeral key is not actually ephemeral

In this case (for example when using TLS), a party could (unilaterally) decide to use a static DH key pair in what is expected to be an ephemeral DH key exchange. This has been proposed a solution for granting access to the plain text to a third party or for computational efficiency reasons.

If the DH private key is persisted (and reused for many handshakes), the key exchange does not provide the expected forward secrecy with respect to this long-lived key[8].

See as well the Racoon attack which exploits a side-channel when Diffie-Hellman key are reused.

Authenticating the Diffie-Hellman key exchange using a shared secret

Authenticating the Diffie-Hellman key exchange using a pre-shared key

We can combine ephemeral-ephemeral Diffie-Hellman with some other secret shared, the pre-shared key (PSK), between the client and the server:

Authenticating the Diffie-Hellman key exchange using a pre-shared key (sequence diagram)

Example: usage in TLS v1.2

In TLS v1.2, both DHE_PSK and ECDHE_PSK key exchanges use this approach.

Example: usage in TLS v1.3

In TLS v1.3, the psk_dhe_ke key exchange mode (i.e., PSK with (EC)DHE) uses this approach.

Warning: low-entropy secret

This method should be used with high entropy PSKs (such as random PSKs). It should not be used for PSKs derived from passwords.

Authenticating the Diffie-Hellman key echange using a password

Other key exchanges based on Diffie-Hellman are designed to be used with low-entropy shared secrets (such as secrets derived from a password).

Examples of authenticating the Diffie-Hellman with a password

For example this approach is used in:

Example: Diffie-Hellman in WPA-SAE

In WPA2-personal (WPA2-PSK), the key exchange does not use a Diffie-Hellman key agreement. Both the station and the AP derive a PSK from the passphrase of the Wifi network[9]. Then, they combine this PSK with the exchanged nonces to derive the key material. Anyone who knows the PSK can compute the encryptions secret keys of previous handshakes (assuming he has observed the nonces) and decrypt the associated Wifi traffic. Therefore, WPA2-personal does not provide forward secrecy with respect to the passphrase/PSK. In WPA-personal, all users of the Wifi network usually[10] share the same secret passphrase/PSK: any of those users can use the shared passphrase/PSK to passively decrypt the traffic of other stations (including previous communications).

WPA3-personal improves this by using WPA-SAE (Simultaneous Authentication of Equals). This combines an ephemeral-ephemeral DH key exchange with the PSK in order to provide forward secrecy with respect to the passphrase/PSK. A passive attacker having access to the PSK cannot decrypt the traffic.

In both cases, an active attacker having access to the passphrase/PSK can impersonate the access point (or join the network and try to use layer 2 attacks such as ARP poisoning, ICMP redirection, etc.).

Conclusion

We have seen how the DH key agreement can be used to generate key material between two parties.

It is usually desirable to authenticate either or both parties in order to protect against active attacks. Each party may be authenticated for example by:

Alternatively, mutual authentication may be achieved by including some shared secret in the key exchange.

Forward secrecy can be achieved by including an ephemeral-ephemeral DH key agreement in the key exchange.

Each party can be protected against replay attacks by contributing some ephemeral value to the key exchange:

Appendix, encryption using Diffie-Hellman

The Diffie-Hellman key exchange protocol can be used for hybrid public-key encryption: both the Elgamal encryption (not discussed here) and the Diffie-Hellman Integrated Encryption Scheme (DHIES) are based on DH. In this context, the receiver cannot contribute any ephemeral value (which could be used to provide forward secrecy and anti-replay protection).

Examples

Several encryption standards have support for encryption based on the Diffie-Hellman key exchange: JWE/JWA, XML encryption, CMS, OpenPGP, etc.

The HPKE (Hybrid Public Key Encryption) public-key encryption scheme uses this approach as well. HPKE is expected to be used in the Encrypted Client Hello (ECH) extension for encrypting the TLS ClientHello message.

Diffie-Hellman Integrated Encryption Scheme

In DHES-based encryption, the sender generates an ephemeral DH key pair and derives a DH shared-secret with the recipient static DH public pair. It then derives some key material from this shared secret which might either be:

Direct DHES-based encryption
DHES-based encryption with key wrapping

Example: DHIES, DLIES and ECIES

Diffie-Hellman Integrated Encryption Scheme (DHIES) uses the direct approach.

The sender:

  1. generates an ephemeral DH keypair;
  2. computes a DHES shared secret from its ephemeral DH private key and the recipient's static DH public key;
  3. derives both a encryption secret key and a MAC key from this DHES shared secret;
  4. encrypt-then-MAC the message using these secret keys.

Discrete Logarithm Integrated Encryption Scheme (DLIES) is DHIES using FFDH. Elliptic Curve Integrated Encryption Scheme (ECIES) is DHIES using ECDH.

Example: DHES encryption in JSON Web Encryption (JWE)

JWE supports both modes:

  • direct mode (ECDH-ES);
  • key wrapping mode (ECDH-ES+A128KW, ECDH-ES+A192KW and ECDH-ES+A256KW).

The ephemeral key is transported in the epk header in JWK form:

{
    "alg":"ECDH-ES",
    "enc":"A128GCM",
    "apu":"QWxpY2U",
    "apv":"Qm9i",
    "epk": {
        "kty":"EC",
        "crv":"P-256",
        "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0",
        "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps"
    }
}

Example: DHES in HPKE base mode

The HPKE base mode with a DH-based key encapsulation method (DHKEM) uses a similar (direct) approach.

The sender:

  1. generates an ephemeral DH keypair (skE, pkE);
  2. computes the DH shared secret (dh) from its ephemeral DH private key and the recipient's static DH public key;
  3. derives (using HKDF) another shared secret (shared_secret) from the DH shared secret and both DH public keys;
  4. derives (using HKDF) a secret key (key) and a base nonce (base_nonce) for an AEAD from this second shared secret;
  5. encrypts (AEAD) the payload (possibly with additional authenticated data) using the secret key and nonce derived (self.ComputeNonce(...)) from the base nonce;
  6. sends the ephemeral DH public key and the ciphertext (ct) to the recipient.

See Encap(), SetupBaseS(), KeySchedule<ROLE>(), ContextS.Seal() and Seal<MODE>().

Encryption based on static-static Diffie-Hellman

If both the sender and the receiver use static DH keys, the sender is authenticated as well (assuming that authenticated encryption is used). A nonce must be included in this case: otherwise the key material would always be the same between the same two parties.

Another advantage of this approach is that the sender can decrypt the message as well (without having to keep the CEK around).

Encryption based on static-static Diffie-Hellman

Note: non-repudiation vs. deniability

This approach provides deniability The receiver cannot prove to a third party that the sender actually created the message: the message could have been forged by the receiver. In contrast, authenticating the sender by sign-then-encrypting the plaintext message would provide non-repudiation.

Either non-repudiation or deniability could be desirable depending on the application:

See for example the OTR paper:

In this paper, we examine what kind of privacy is necessary for social communications. We argue that not only must encryption be used to hide the contents of the conversation, but also, the encryption must provide perfect forward secrecy to protect from future compromises. Additionally, authentication must be used to ensure that the person on the other end is who they claim to be. However, the authentication mechanism must offer repudiation, so that the communications remain personal and unverifiable to third parties. Only with these properties can privacy similar to real-world social communications be achieved.

Warning: Key Compromise Impersonation

As before, if an attacker manages to compromise the static DH private key of Alice, it can then use this key to impersonate every other party (Bob) when talking to Alice.

Combining static-static and ephemeral-static Diffie-Hellman

The HPKE scheme in authenticated mode with DHKEM uses a similar approach to provide public-key authenticated encryption. Instead of using a nonce, the sender combines a static-static DH key agreement and a DHES key agreement:

The sender and the receiver both derive the key material from both DH shared secrets and the three DH public keys.

HPKE in authenticated mode using DHKEM

Warning: Key Compromise Impersonation

This approach is vulnerable to KCI as well.

Appendix, mathematical considerations

Diffie-Hellman parameters

The two parties first agree on a finite cyclic group (𝒢, .) to use for the Diffie-Hellman exchange and a generator g ∈ 𝒢 of this group. The choice of these two parameters may be hardcoded in the protocol/implementation/configuration or could be negotiated in some way.

Let n the order of the group, we have |𝒢| = n and 𝒢 = { gi : i ∈ {0, …, n - 1} }. In other words, the function f(i) = gi is a bijection from {0, …, n - 1} (or equivalently ℤ/nℤ) to 𝒢.

Note: notations (additive group vs. multiplicative group)

In this post, we are considering the group as an multiplicative group (𝒢, .). Some papers use the additive notation (𝒢, +) instead: this is purely a difference in the notation. You will find a summary of the two notations in the table below.

Key generation

Summary:

For generating a DH private key, a party chooses a random integer 1 < ka < n: this value is the private key. The associated DH public key is the corresponding element of 𝒢: Ka = gka ∈ 𝒢.

This is only interesting if we are working in a group 𝒢 where computing the private key ka from the public key Ka (discrete logarithm problem) is not tractable. One necessary condition is for n to be large enough for a brute-force approach to be intractable.

Key agreement

Once two parties Alice and Bob have exchanged their DH public keys Ka and Kb, they can compute the same DH shared secret z:

The two parties compute the same value because Kbka = (gkb)ka = g kb.ka = g ka.kb = (gka)kb = Kakb.

Generator g;
              Alice's private key ka;
              Alice's public key Ka = ka.g;
              Bob's private key kb;
              Bob's public key Kb = kb.g;
              DH shared secret: z = ka.kb.g = kb.ka.kg
Graphical representation of the DH shared secret computation

An attacker knows Ka and Kb but not ka and kb and cannot reproduce any of these two computations. In order to compute the DH shared secret z, the attacker has to solve the Computational Diffie-Hellman problem. One way to solve this problem would be to solve the discrete logarithm problem. Moreover, solving the Computational Diffie-Hellman problem is equivalent to the discrete logarithm problem for many classes of groups.

Notations Summary

Conversion table between the additive and multiplicative notation
Multiplicative group Additive group
Group (𝒢, .) (𝒢, +)
Group operation x . y ∈ 𝒢 x + y ∈ 𝒢
Group exponentiation xi = x . … . x ∈ 𝒢 (i times) i . x = x + … + x ∈ 𝒢 (i times)
Generator (g ∈ 𝒢) 𝒢 = { gi : i ∈ {0, …, n - 1} }. 𝒢 = { i.g : i ∈ {0, …, n - 1} }
DH private key ka < n ka < n
DH public key Ka = gka ∈ 𝒢 Ka = ka.g ∈ 𝒢
DH shared secret z = Kakb = Kbka = gka.kb ∈ 𝒢 z = kb . Ka = ka . Kb = ka . kb . g ∈ 𝒢
Discrete Logarithm problem Given gk, find k ∈ {0, …, n - 1} Given k.g ∈ 𝒢, find k ∈ {0, …, n - 1}
Computational DH problem Given g ∈ 𝒢, gk ∈ 𝒢 and gk' ∈ 𝒢, find gk.k' Given g ∈ 𝒢, k.g ∈ 𝒢 and k'.g ∈ 𝒢, find k.k'.g.

Where:

Generator g;
              Alice's private key ka;
              Alice's public key Ka = ka.g;
              Bob's private key kb;
              Bob's public key Kb = kb.g;
              DH shared secret: z = ka.kb.g = kb.ka.kg
Graphical representation of the DH shared secret computation (additive group)

Appendix, RSA key exchange

The following diagram represents the classic RSA transport key exchange as featured in old TLS ciphersuites (RSA-Encrypted Premaster Secret).

Static RSA key exchange

In this scheme, the TLS client would send a premaster secret (z) to the server encrypted with the (usually static) server RSA public key[11]:

struct {
    public-key-encrypted PreMasterSecret pre_master_secret;
} EncryptedPreMasterSecret;

struct {
    select (KeyExchangeAlgorithm) {
        case rsa:
            EncryptedPreMasterSecret;
        case dhe_dss:
        case dhe_rsa:
        case dh_dss:
        case dh_rsa:
        case dh_anon:
            ClientDiffieHellmanPublic;
    } exchange_keys;
} ClientKeyExchange;

This does not provide forward secrecy with respect to the server static RSA private key and its usage is therefore deprecated in TLS.

It is possible to get forward secrecy by using an ephemeral RSA keypair. As far as I known, this approach is not used in practice because generating RSA keys is computationally expensive.

Unauthenticated ephemeral RSA key exchange (sequence diagram)

The key exchange in the previous figure is not authenticated (and is therefore vulnerable to active attacks). As for the ephemeral Diffie-Hellman key exchange, you need to add signatures, nonces and key confirmation in order to secure against active attackers.

Note: Usage of ephemeral RSA keys in TLS

This usage of ephemeral RSA keys was was possible in TLS 1.0 when using the (infamous) RSA_EXPORT ciphersuites. In this case, the ServerKeyExchange message would contain a RSA public key which would be different from the static RSA key found in the server certificate:

/* TLS 1.1 */
struct {
      select (KeyExchangeAlgorithm) {
          case diffie_hellman:
              ServerDHParams params;
              Signature signed_params;
          case rsa:                    /* Message only send when using RSA_EXPORT */
              ServerRSAParams params;  /* might be an ephemeral RSA public key */
              Signature signed_params; /* using static RSA key bound to server certificate */
      };
} ServerKeyExchange;

When using these ciphersuites, a deliberately weak (512-bit) (export) RSA key was sent by the server and used for encrypting the premaster secret (instead of the much stronger RSA key associated with the certificate). In practice, the same RSA keypair was apparently often reused for a long time because generation of RSA keypairs is computationally expensive.

This is discussed in the security analysis of the TLS 1.1 RFC (note that this section appears to really apply to TLS 1.0):

With RSA, key exchange and server authentication are combined. The public key either may be contained in the server's certificate or may be a temporary RSA key sent in a server key exchange message. When temporary RSA keys are used, they are signed by the server's RSA certificate. The signature includes the current ClientHello.random, so old signatures and temporary keys cannot be replayed. Servers may use a single temporary RSA key for multiple negotiation sessions.

Note: The temporary RSA key option is useful if servers need large certificates but must comply with government-imposed size limits on keys used for key exchange.

Note that if ephemeral RSA is not used, compromise of the server's static RSA key results in a loss of confidentiality for all sessions protected under that static key. TLS users desiring Perfect Forward Secrecy should use DHE cipher suites. [...]

In TLS 1.1, the RSA_EXPORT ciphersuites were removed. The RSA keypair used in TLS_RSA ciphersuites is always the RSA keypair associated with the server certificate and the ephemeral RSA cannot be used.

References

Digital signatures, non-repudiation and deniability:

Backlinks:


  1. Eve is traditionally used to designate an eavesdropper (a passive attacker). This type of attacker is able to see the message on the network but cannot modify, send or intercept messages. ↩︎

  2. Mallory is traditionally used to designate an active attacker. This type of attacker is able to spoof, alter and intercept message. ↩︎

  3. If the encryption scheme is an authenticated encryption, there is no need for a separate MAC. ↩︎

  4. Using a key derivation function (KDF). For example, TLS v1.3 uses HKDF. ↩︎ ↩︎

  5. In the case where Alice is authenticating using a static DH key pair and Bob is authenticating using a digital signature, Alice is vulnerable to KCI as well: if an attacker manages to get Alice's static DH private key, the attacker can use that key to compute the DH shared secret and hijack the communication. ↩︎

  6. This is the extended version of protocol 1 in Modular Security Proofs for Key Agreemen Protocols, discussed at the end of section 5. ↩︎

  7. “What about a double Diffie-Hellman key agreement?”, you might wonder.

    If you don't include the ephemeral-ephemeral DH key agreeement (only the two ephemeral-static ones), you don't have forward secrecy with respect to the static DH private keys: if someone manages to compromise the static DH private key of both participants, he can then compute both DH shared secrets and decrypt all previous communications between these two parties. This is protocol 1 in Modular Security Proofs for Key Agreemen Protocols.

    Another option would be to combine an ephemeral-ephemeral DH key exchange (for mutual authentication) and a static-static DH key exchange (for forward secrecy). I guess (?) it would work but would provide weaker participation repudiation than 3DH: it would only provide participation repudiation (when any of the two parties can forge a transcript between the two parties) instead of the full participation repudiation (when “anybody is able to forge a transcript between any two parties”) provided by 3DH. Moreover, this scheme would be vulnerable to KCI because the authentication would be based on a static-static DH key exchange. [citation neeeded] ↩︎

  8. One might argue that a party should try to detect DH key reuse when communicating with peers and reject the key exchange in this case. ↩︎

  9. The PSK is derived from the Wifi password and the SSID using a password-based key derivation function (PBKDF2-HMAC-SHA1):

    PSK = PBKDF2-HMAC-SHA1(passphrase, salt=SSID, iterations=4096, 256 bits)
    

    See for example Analysis of the 802.11i 4-Way Handshake or How does WPA/WPA2 WiFi security work, and how to crack it? for details. ↩︎

  10. See the wpa_psk_file configuration in hostapd for a solution to have per-station (i.e., per MAC address) Wifi passphrases. ↩︎

  11. With the RSAES-PKCS1-v1_5 scheme. ↩︎