Danger

This is a “Hazardous Materials” module. You should ONLY use it if you’re 100% absolutely sure that you know what you’re doing because this module is full of land mines, dragons, and dinosaurs with laser guns.

Diffie-Hellman key exchange

Note

For security and performance reasons we suggest using ECDH instead of DH where possible.

Diffie-Hellman key exchange (D–H) is a method that allows two parties to jointly agree on a shared secret using an insecure channel.

Exchange Algorithm

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.

>>> 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())
>>> # Generate a private key for use in the exchange.
>>> private_key = parameters.generate_private_key()
>>> # In a real handshake the peer_public_key will be received from the
>>> # other party. For this example we'll generate another private key and
>>> # get a public key from that. Note that in a DH handshake both peers
>>> # 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 generate a new private key using generate_private_key() for each exchange() when performing an DHE key exchange. This is demonstrated in the previous example.

To assemble a DHParameters and a DHPublicKey from primitive integers, you must first create the DHParameterNumbers and DHPublicNumbers objects. For example, if p, g, and y are int objects received from a peer:

pn = dh.DHParameterNumbers(p, g)
parameters = pn.parameters(default_backend())
peer_public_numbers = dh.DHPublicNumbers(y, pn)
peer_public_key = peer_public_numbers.public_key(default_backend())

See also the DHBackend API for additional functionality.

Group parameters

cryptography.hazmat.primitives.asymmetric.dh.generate_parameters(generator, key_size, backend)[source]

New in version 1.7.

Generate a new DH parameter group for use with backend.

Parameters:
  • generator – The int to use as a generator. Must be 2 or 5.
  • key_size – The bit length of the prime modulus to generate.
  • backend – A DHBackend instance.
Returns:

DH parameters as a new instance of DHParameters.

Raises:

ValueError – If key_size is not at least 512.

class cryptography.hazmat.primitives.asymmetric.dh.DHParameters[source]

New in version 1.7.

generate_private_key()[source]

Generate a DH private key. This method can be used to generate many new private keys from a single set of parameters.

Returns:An instance of DHPrivateKey.
parameter_numbers()[source]

Return the numbers that make up this set of parameters.

Returns:A DHParameterNumbers.
parameter_bytes(encoding, format)[source]

New in version 2.0.

Allows serialization of the parameters to bytes. Encoding ( PEM or DER) and format ( PKCS3) are chosen to define the exact serialization.

Parameters:
  • encoding – A value from the Encoding enum.
  • format – A value from the ParameterFormat enum. At the moment only PKCS3 is supported.
Return bytes:

Serialized parameters.

class cryptography.hazmat.primitives.asymmetric.dh.DHParametersWithSerialization

New in version 1.7.

Alias for DHParameters.

Key interfaces

class cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKey[source]

New in version 1.7.

A DH private key that is not an opaque key also implements DHPrivateKeyWithSerialization to provide serialization methods.

key_size

The bit length of the prime modulus.

public_key()[source]

Return the public key associated with this private key.

Returns:A DHPublicKey.
parameters()[source]

Return the parameters associated with this private key.

Returns:A DHParameters.
exchange(peer_public_key)[source]

New in version 1.7.

Parameters:peer_public_key (DHPublicKey) – The public key for the peer.
Return bytes:The agreed key. The bytes are ordered in ‘big’ endian.
class cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKeyWithSerialization[source]

New in version 1.7.

This interface contains additional methods relating to serialization. Any object with this interface also has all the methods from DHPrivateKey.

private_numbers()[source]

Return the numbers that make up this private key.

Returns:A DHPrivateNumbers.
private_bytes(encoding, format, encryption_algorithm)[source]

New in version 1.8.

Allows serialization of the key to bytes. Encoding ( PEM or DER), format ( PKCS8) and encryption algorithm (such as BestAvailableEncryption or NoEncryption) are chosen to define the exact serialization.

Parameters:
Return bytes:

Serialized key.

class cryptography.hazmat.primitives.asymmetric.dh.DHPublicKey[source]

New in version 1.7.

key_size

The bit length of the prime modulus.

parameters()[source]

Return the parameters associated with this private key.

Returns:A DHParameters.
public_numbers()[source]

Return the numbers that make up this public key.

Returns:A DHPublicNumbers.
public_bytes(encoding, format)[source]

New in version 1.8.

Allows serialization of the key to bytes. Encoding ( PEM or DER) and format ( SubjectPublicKeyInfo) are chosen to define the exact serialization.

Parameters:
Return bytes:

Serialized key.

class cryptography.hazmat.primitives.asymmetric.dh.DHPublicKeyWithSerialization

New in version 1.7.

Alias for DHPublicKey.

Numbers

class cryptography.hazmat.primitives.asymmetric.dh.DHParameterNumbers(p, g, q=None)[source]

New in version 0.8.

The collection of integers that define a Diffie-Hellman group.

p
Type:int

The prime modulus value.

g
Type:int

The generator value. Must be 2 or greater.

q

New in version 1.8.

Type:int

p subgroup order value.

parameters(backend)[source]

New in version 1.7.

Parameters:backend – An instance of DHBackend.
Returns:A new instance of DHParameters.
class cryptography.hazmat.primitives.asymmetric.dh.DHPrivateNumbers(x, public_numbers)[source]

New in version 0.8.

The collection of integers that make up a Diffie-Hellman private key.

public_numbers
Type:DHPublicNumbers

The DHPublicNumbers which makes up the DH public key associated with this DH private key.

x
Type:int

The private value.

private_key(backend)[source]

New in version 1.7.

Parameters:backend – An instance of DHBackend.
Returns:A new instance of DHPrivateKey.
class cryptography.hazmat.primitives.asymmetric.dh.DHPublicNumbers(y, parameter_numbers)[source]

New in version 0.8.

The collection of integers that make up a Diffie-Hellman public key.

parameter_numbers
Type:DHParameterNumbers

The parameters for this DH group.

y
Type:int

The public value.

public_key(backend)[source]

New in version 1.7.

Parameters:backend – An instance of DHBackend.
Returns:A new instance of DHPublicKey.