1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
.. 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
|