177 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
.. 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.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',
 | 
						|
    ... ).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',
 | 
						|
    ... ).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
 |