You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
6.7 KiB
180 lines
6.7 KiB
.. hazmat::
|
|
|
|
X448 key exchange
|
|
===================
|
|
|
|
.. currentmodule:: cryptography.hazmat.primitives.asymmetric.x448
|
|
|
|
|
|
X448 is an elliptic curve `Diffie-Hellman key exchange`_ using `Curve448`_.
|
|
It 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.
|
|
|
|
.. doctest::
|
|
|
|
>>> from cryptography.hazmat.backends import default_backend
|
|
>>> from cryptography.hazmat.primitives import hashes
|
|
>>> from cryptography.hazmat.primitives.asymmetric.x448 import X448PrivateKey
|
|
>>> from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
|
>>> # Generate a private key for use in the exchange.
|
|
>>> private_key = X448PrivateKey.generate()
|
|
>>> # 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 = X448PrivateKey.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 = X448PrivateKey.generate()
|
|
>>> peer_public_key_2 = X448PrivateKey.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
|
|
~~~~~~~~~~~~~~
|
|
|
|
.. class:: X448PrivateKey
|
|
|
|
.. versionadded:: 2.5
|
|
|
|
.. classmethod:: generate()
|
|
|
|
Generate an X448 private key.
|
|
|
|
:returns: :class:`X448PrivateKey`
|
|
|
|
.. classmethod:: from_private_bytes(data)
|
|
|
|
:param data: 56 byte private key.
|
|
:type data: :term:`bytes-like`
|
|
|
|
:returns: :class:`X448PrivateKey`
|
|
|
|
.. doctest::
|
|
|
|
>>> from cryptography.hazmat.primitives import serialization
|
|
>>> from cryptography.hazmat.primitives.asymmetric import x448
|
|
>>> private_key = x448.X448PrivateKey.generate()
|
|
>>> private_bytes = private_key.private_bytes(
|
|
... encoding=serialization.Encoding.Raw,
|
|
... format=serialization.PrivateFormat.Raw,
|
|
... encryption_algorithm=serialization.NoEncryption()
|
|
... )
|
|
>>> loaded_private_key = x448.X448PrivateKey.from_private_bytes(private_bytes)
|
|
|
|
.. method:: public_key()
|
|
|
|
:returns: :class:`X448PublicKey`
|
|
|
|
.. method:: exchange(peer_public_key)
|
|
|
|
:param X448PublicKey peer_public_key: The public key for the
|
|
peer.
|
|
|
|
:returns bytes: A shared key.
|
|
|
|
.. method:: private_bytes(encoding, format, encryption_algorithm)
|
|
|
|
Allows serialization of the key to bytes. Encoding (
|
|
:attr:`~cryptography.hazmat.primitives.serialization.Encoding.PEM`,
|
|
:attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER`, or
|
|
:attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw`) and
|
|
format (
|
|
:attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8`
|
|
or
|
|
:attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.Raw`
|
|
) are chosen to define the exact serialization.
|
|
|
|
:param encoding: A value from the
|
|
:class:`~cryptography.hazmat.primitives.serialization.Encoding` enum.
|
|
|
|
:param format: A value from the
|
|
:class:`~cryptography.hazmat.primitives.serialization.PrivateFormat`
|
|
enum. If the ``encoding`` is
|
|
:attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw`
|
|
then ``format`` must be
|
|
:attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.Raw`
|
|
, otherwise it must be
|
|
:attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8`.
|
|
|
|
:param encryption_algorithm: An instance of an object conforming to the
|
|
:class:`~cryptography.hazmat.primitives.serialization.KeySerializationEncryption`
|
|
interface.
|
|
|
|
:return bytes: Serialized key.
|
|
|
|
.. class:: X448PublicKey
|
|
|
|
.. versionadded:: 2.5
|
|
|
|
.. classmethod:: from_public_bytes(data)
|
|
|
|
:param bytes data: 56 byte public key.
|
|
|
|
:returns: :class:`X448PublicKey`
|
|
|
|
.. doctest::
|
|
|
|
>>> from cryptography.hazmat.primitives import serialization
|
|
>>> from cryptography.hazmat.primitives.asymmetric import x448
|
|
>>> private_key = x448.X448PrivateKey.generate()
|
|
>>> public_key = private_key.public_key()
|
|
>>> public_bytes = public_key.public_bytes(
|
|
... encoding=serialization.Encoding.Raw,
|
|
... format=serialization.PublicFormat.Raw
|
|
... )
|
|
>>> loaded_public_key = x448.X448PublicKey.from_public_bytes(public_bytes)
|
|
|
|
.. method:: public_bytes(encoding, format)
|
|
|
|
Allows serialization of the key to bytes. Encoding (
|
|
:attr:`~cryptography.hazmat.primitives.serialization.Encoding.PEM`,
|
|
:attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER`, or
|
|
:attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw`) and
|
|
format (
|
|
:attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo`
|
|
or
|
|
:attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.Raw`
|
|
) are chosen to define the exact serialization.
|
|
|
|
:param encoding: A value from the
|
|
:class:`~cryptography.hazmat.primitives.serialization.Encoding` enum.
|
|
|
|
:param format: A value from the
|
|
:class:`~cryptography.hazmat.primitives.serialization.PublicFormat`
|
|
enum. If the ``encoding`` is
|
|
:attr:`~cryptography.hazmat.primitives.serialization.Encoding.Raw`
|
|
then ``format`` must be
|
|
:attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.Raw`
|
|
, otherwise it must be
|
|
:attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo`.
|
|
|
|
:returns bytes: The public key bytes.
|
|
|
|
|
|
.. _`Diffie-Hellman key exchange`: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
|
|
.. _`Curve448`: https://en.wikipedia.org/wiki/Curve448
|