Document motivation for a KDF after key-exchange (#4005) (#4124)

This commit is contained in:
Jeremy Lainé 2018-03-05 19:05:38 +01:00 committed by Paul Kehrer
parent 62303cc9dc
commit d87f80619b
3 changed files with 64 additions and 5 deletions

View file

@ -19,12 +19,16 @@ Exchange Algorithm
~~~~~~~~~~~~~~~~~~
For most applications the ``shared_key`` should be passed to a key
derivation function.
derivation function. This allows mixing of additional information into the
key, derivation of multiple keys, and destroys any structure that may be
present.
.. code-block:: pycon
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import dh
>>> from cryptography.hazmat.primitives.kdf.hkdf import HKDF
>>> # Generate some parameters. These can be reused.
>>> parameters = dh.generate_parameters(generator=2, key_size=2048,
... backend=default_backend())
@ -36,11 +40,26 @@ derivation function.
>>> # must agree on a common set of parameters.
>>> peer_public_key = parameters.generate_private_key().public_key()
>>> shared_key = private_key.exchange(peer_public_key)
>>> # Perform key derivation.
>>> derived_key = HKDF(
... algorithm=hashes.SHA256(),
... length=32,
... salt=None,
... info=b'handshake data',
... backend=default_backend()
... ).derive(shared_key)
>>> # For the next handshake we MUST generate another private key, but
>>> # we can reuse the parameters.
>>> private_key_2 = parameters.generate_private_key()
>>> peer_public_key_2 = parameters.generate_private_key().public_key()
>>> shared_key_2 = private_key_2.exchange(peer_public_key_2)
>>> derived_key_2 = HKDF(
... algorithm=hashes.SHA256(),
... length=32,
... salt=None,
... info=b'handshake data',
... backend=default_backend()
... ).derive(shared_key_2)
DHE (or EDH), the ephemeral form of this exchange, is **strongly
preferred** over simple DH and provides `forward secrecy`_ when used. You must

View file

@ -226,12 +226,16 @@ Elliptic Curve Key Exchange algorithm
in NIST publication `800-56A`_, and later in `800-56Ar2`_.
For most applications the ``shared_key`` should be passed to a key
derivation function.
derivation function. This allows mixing of additional information into the
key, derivation of multiple keys, and destroys any structure that may be
present.
.. doctest::
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import ec
>>> from cryptography.hazmat.primitives.kdf.hkdf import HKDF
>>> # Generate a private key for use in the exchange.
>>> private_key = ec.generate_private_key(
... ec.SECP384R1(), default_backend()
@ -243,6 +247,14 @@ Elliptic Curve Key Exchange algorithm
... ec.SECP384R1(), default_backend()
... ).public_key()
>>> shared_key = private_key.exchange(ec.ECDH(), peer_public_key)
>>> # Perform key derivation.
>>> derived_key = HKDF(
... algorithm=hashes.SHA256(),
... length=32,
... salt=None,
... info=b'handshake data',
... backend=default_backend()
... ).derive(shared_key)
>>> # For the next handshake we MUST generate another private key.
>>> private_key_2 = ec.generate_private_key(
... ec.SECP384R1(), default_backend()
@ -251,6 +263,13 @@ Elliptic Curve Key Exchange algorithm
... ec.SECP384R1(), default_backend()
... ).public_key()
>>> shared_key_2 = private_key_2.exchange(ec.ECDH(), peer_public_key_2)
>>> derived_key_2 = HKDF(
... algorithm=hashes.SHA256(),
... length=32,
... salt=None,
... info=b'handshake data',
... backend=default_backend()
... ).derive(shared_key_2)
ECDHE (or EECDH), the ephemeral form of this exchange, is **strongly
preferred** over simple ECDH and provides `forward secrecy`_ when used.
@ -453,8 +472,10 @@ Key Interfaces
Performs a key exchange operation using the provided algorithm with
the peer's public key.
For most applications the result should be passed to a key derivation
function.
For most applications the ``shared_key`` should be passed to a key
derivation function. This allows mixing of additional information into the
key, derivation of multiple keys, and destroys any structure that may be
present.
:param algorithm: The key exchange algorithm, currently only
:class:`~cryptography.hazmat.primitives.asymmetric.ec.ECDH` is

View file

@ -15,12 +15,16 @@ Exchange Algorithm
~~~~~~~~~~~~~~~~~~
For most applications the ``shared_key`` should be passed to a key
derivation function.
derivation function. This allows mixing of additional information into the
key, derivation of multiple keys, and destroys any structure that may be
present.
.. doctest::
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
>>> from cryptography.hazmat.primitives.kdf.hkdf import HKDF
>>> # Generate a private key for use in the exchange.
>>> private_key = X25519PrivateKey.generate()
>>> # In a real handshake the peer_public_key will be received from the
@ -29,10 +33,25 @@ derivation function.
>>> # must agree on a common set of parameters.
>>> peer_public_key = X25519PrivateKey.generate().public_key()
>>> shared_key = private_key.exchange(peer_public_key)
>>> # Perform key derivation.
>>> derived_key = HKDF(
... algorithm=hashes.SHA256(),
... length=32,
... salt=None,
... info=b'handshake data',
... backend=default_backend()
... ).derive(shared_key)
>>> # For the next handshake we MUST generate another private key.
>>> private_key_2 = X25519PrivateKey.generate()
>>> peer_public_key_2 = X25519PrivateKey.generate().public_key()
>>> shared_key_2 = private_key_2.exchange(peer_public_key_2)
>>> derived_key_2 = HKDF(
... algorithm=hashes.SHA256(),
... length=32,
... salt=None,
... info=b'handshake data',
... backend=default_backend()
... ).derive(shared_key_2)
Key interfaces
~~~~~~~~~~~~~~