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: 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
orDER
) 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 onlyPKCS3
is supported.
Return bytes: Serialized parameters.
- encoding – A value from the
-
-
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
orDER
), format (PKCS8
) and encryption algorithm (such asBestAvailableEncryption
orNoEncryption
) are chosen to define the exact serialization.Parameters: - encoding – A value from the
Encoding
enum. - format – A value from the
PrivateFormat
enum. - encryption_algorithm – An instance of an object conforming to the
KeySerializationEncryption
interface.
Return bytes: Serialized key.
- encoding – A value from the
-
-
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
orDER
) and format (SubjectPublicKeyInfo
) are chosen to define the exact serialization.Parameters: - encoding – A value from the
Encoding
enum. - format – A value from the
PublicFormat
enum.
Return bytes: Serialized key.
- encoding – A value from the
-
-
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.
-
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.
-
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.
-
public_key
(backend)[source]¶ New in version 1.7.
Parameters: backend – An instance of DHBackend
.Returns: A new instance of DHPublicKey
.
-