Hi I'm trying to piece together how AES, ECDHE, and SHA all work together. From what I understand ECDHE is uses asymmetric cryptography to generate a shared key from a public and private key which are mathematically related based on points off the ecliptic curve. AES is used for encryption and decryption and requires a key. SHA is a hashing function that is used for message authentication and data integrity but it can also be like a KDF (even though it isn't one) to generate a key for AES. Where does ECDHE fit into this. Aren't the keys that are exchanged initially in ECDHE used in AES? Does AES take in two different types of keys? I've been trying to wrap my head around this but I'm not exactly so sure why we need 2 sets of keys (a shared key from ECDHE and also a generated key from SHA or some other KDF that uses SHA).

  • 2
    $\begingroup$ security.stackexchange.com is chock full of "how TLS works", read any of them. Read the TLS 1.2 or TLS 1.3 RFC. $\endgroup$ – Z.T. Jun 8 at 19:05
  • $\begingroup$ @Z.T.: I suspect the question wasn't meant to be TLS-specific $\endgroup$ – poncho Jun 8 at 19:59
  • $\begingroup$ @poncho an explanation of TLS would work for anything else, even libsodium. $\endgroup$ – Z.T. Jun 8 at 20:02

Diffie-Hellman gives you a shared secret.

Something like CBC + HMAC needs a key for the block cipher and a key for the MAC. CTR + HMAC would need a key for the block cipher and a key for the MAC. An AEAD needs a key. These parameters are usually needed twice: one set for transmit (tx) and one set for receive (rx), or client to server and server to client. So you need to get some number of bytes of key material out of your shared secret you got using DH. The exact numbers doesn't matter.

X25519 ECDH gives you 32 bytes of shared secret. Not enough.

You use a KDF to stretch those 32 bytes to the 2*(32+32), 2*32 (or whatever) bytes you need.

If you need to encrypt more bytes than you're allowed to encrypt using a single key, you need to use the KDF to get even more key material out of the shared secret (though it would be better maybe to just split the file and transmit using separate connections, each using no more than the allowed number of bytes).

Here, for example, is libsodium doing X25519 ECDH and then using Blake2b as KDF to produce key material: https://github.com/jedisct1/libsodium/blob/stable/src/libsodium/crypto_kx/crypto_kx.c#L34

Here are the TLS RFCs telling you how to do that for TLS (a much more complicated protocol than NaCl/libsodium).

TLS 1.2:

ECDH to premaster secret: https://tools.ietf.org/html/rfc4492#section-5.10

pre master secret to master secret: https://tools.ietf.org/html/rfc5246#section-8.1

master secret to keys: https://tools.ietf.org/html/rfc5246#section-6.3

TLS 1.3:

ECDH to master secret: https://tools.ietf.org/html/rfc8446#section-7.4.2

master secret to keys: https://tools.ietf.org/html/rfc8446#section-7.1


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.