Why don't client and server just exchange the encryption keys directly using public key encryption or DH key exchange protocol? What the rationale behind that or what the problem it is to solve?
Its helpful to understand how keys are derived in modern SSL/TLS. Things were a bit different in early SSL (like SSLv2).
The master_secret
is a common secret shared by the client and server. It is used to derive session specific keys. The master_secret
derived form other parameters (discussed below).
There are 6 each secrets derived from the master_secret
:
Assuming that neither eNULL
nor aNULL
is used, both the client and server use an encryption key for confidentiality and a HMAC key for authenticity. Each (client and server) has its own key.
While IVs are usually considered public, SSL/TLS treats them as secret parameters.
From RFC 5246, the master_secret
is derived as:
master_secret = PRF(pre_master_secret, "master secret",
ClientHello.random + ServerHello.random)
[0..47];
The pre_master_secret
comes from key agreement or key transport. If it comes from key agreement, then the pre_master_secret
is the result of Diffie-Hellman key agreement. In an agreement scheme, both parties contribute to the derived secret.
If the pre_master_secret
comes from a key transport scheme, then the client encrypts a random value under the server's public key. In this scheme, only the client provides keying material. When only one party provides the key, its called a key transport scheme.
What the rationale behind that or what the problem it is to solve?
The first stage, where the pre_master_secret
is used, provides a "pluggable" architecture for key agreement or key transport.
The second stage, where the master_secret
is derived, ensures both the client and server contribute to the keying material.
In addition, there's a label - "master secret" - that helps ensure derivation is unique even if the same parameters are used for something else (assuming a different derivation uses a different label). Use of labels are discussed in SP800-56 and SP800-57 (among other places).
The hash used in the second stage, where the master_secret
is derived, performs two functions. First, it performs a mixing function. Second, it maps elements in the group used by key exchange or key agreement into random bit patterns.
The final stage is the derivation of the 6 keys from master_secret
. According to 6.3. Key Calculation, the derivation does not provide key independence. It just ensures interoperability:
To generate the key material, compute
key_block = PRF(SecurityParameters.master_secret,
"key expansion",
SecurityParameters.server_random +
SecurityParameters.client_random);
until enough output has been generated. Then, the key_block is
partitioned as follows:
client_write_MAC_key[SecurityParameters.mac_key_length]
server_write_MAC_key[SecurityParameters.mac_key_length]
client_write_key[SecurityParameters.enc_key_length]
server_write_key[SecurityParameters.enc_key_length]
client_write_IV[SecurityParameters.fixed_iv_length]
server_write_IV[SecurityParameters.fixed_iv_length]
The steps above are a solid design. However, when used in SSL/TLS, there are lots of devils running around. For example, the above is not enough when a feature like renegotiation is added (triple handshake attack ftw!).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With