>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import ec
>>> from cryptography.hazmat.primitives.kdf.hkdf import HKDF
>>> # Generate a private key for use in the exchange.
>>> private_key = ec.generate_private_key(
... ec.SECP384R1()
... )
>>> # 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.
>>> peer_public_key = ec.generate_private_key(
... ec.SECP384R1()
... ).public_key()
>>> shared_key = private_key.exchange(ec.ECDH(), 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 = ec.generate_private_key(
... ec.SECP384R1()
... )
>>> peer_public_key_2 = ec.generate_private_key(
... ec.SECP384R1()
... ).public_key()
>>> shared_key_2 = private_key_2.exchange(ec.ECDH(), peer_public_key_2)
>>> derived_key_2 = HKDF(
... algorithm=hashes.SHA256(),
... length=32,
... salt=None,
... info=b'handshake data',
... ).derive(shared_key_2)
Elliptic Curves
Elliptic curves provide equivalent security at much smaller key sizes than
other asymmetric cryptography systems such as RSA or DSA. For many operations
elliptic curves are also significantly faster; elliptic curve diffie-hellman
is faster than diffie-hellman.
Curves with a size of less than 224 bits should not be used. You should
strongly consider using curves of at least 224 bits.
Generally the NIST prime field (“P”) curves are significantly faster than the
other types suggested by NIST at both signing and verifying with ECDSA.
Prime fields also minimize the number of security concerns for elliptic-curve
cryptography. However, there is some concern that both the prime field and
binary field (“B”) NIST curves may have been weakened during their generation.
Currently cryptography only supports NIST curves, none of which are
considered “safe” by the SafeCurves project run by Daniel J. Bernstein and
Tanja Lange.
All named curves are instances of EllipticCurve
.
class cryptography.hazmat.primitives.asymmetric.ec.SECP256R1[source]
Added in version 0.5.
SECG curve secp256r1
. Also called NIST P-256.
class cryptography.hazmat.primitives.asymmetric.ec.SECP384R1[source]
Added in version 0.5.
SECG curve secp384r1
. Also called NIST P-384.
class cryptography.hazmat.primitives.asymmetric.ec.SECP521R1[source]
Added in version 0.5.
SECG curve secp521r1
. Also called NIST P-521.
class cryptography.hazmat.primitives.asymmetric.ec.SECP224R1[source]
Added in version 0.5.
SECG curve secp224r1
. Also called NIST P-224.
class cryptography.hazmat.primitives.asymmetric.ec.SECP192R1[source]
Added in version 0.5.
SECG curve secp192r1
. Also called NIST P-192.
class cryptography.hazmat.primitives.asymmetric.ec.SECP256K1[source]
Added in version 0.9.
SECG curve secp256k1
.
class cryptography.hazmat.primitives.asymmetric.ec.BrainpoolP256R1[source]
Added in version 2.2.
Brainpool curve specified in RFC 5639. These curves are discouraged
for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.BrainpoolP384R1[source]
Added in version 2.2.
Brainpool curve specified in RFC 5639. These curves are discouraged
for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.BrainpoolP512R1[source]
Added in version 2.2.
Brainpool curve specified in RFC 5639. These curves are discouraged
for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT571K1[source]
Added in version 0.5.
SECG curve sect571k1
. Also called NIST K-571. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT409K1[source]
Added in version 0.5.
SECG curve sect409k1
. Also called NIST K-409. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT283K1[source]
Added in version 0.5.
SECG curve sect283k1
. Also called NIST K-283. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT233K1[source]
Added in version 0.5.
SECG curve sect233k1
. Also called NIST K-233. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT163K1[source]
Added in version 0.5.
SECG curve sect163k1
. Also called NIST K-163. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT571R1[source]
Added in version 0.5.
SECG curve sect571r1
. Also called NIST B-571. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT409R1[source]
Added in version 0.5.
SECG curve sect409r1
. Also called NIST B-409. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT283R1[source]
Added in version 0.5.
SECG curve sect283r1
. Also called NIST B-283. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT233R1[source]
Added in version 0.5.
SECG curve sect233r1
. Also called NIST B-233. These binary curves are
discouraged for new systems.
class cryptography.hazmat.primitives.asymmetric.ec.SECT163R2[source]
Added in version 0.5.
SECG curve sect163r2
. Also called NIST B-163. These binary curves are
discouraged for new systems.
Key Interfaces
class cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve[source]
Added in version 0.5.
A named elliptic curve.
name
Type:
The name of the curve. Usually the name used for the ASN.1 OID such as
secp256k1
.
class cryptography.hazmat.primitives.asymmetric.ec.EllipticCurveSignatureAlgorithm[source]
Added in version 0.5.
Changed in version 1.6: Prehashed
can now be used as an algorithm
.
A signature algorithm for use with elliptic curve keys.
algorithm
Type:
HashAlgorithm
or
Prehashed
The digest algorithm to be used with the signature scheme.
class cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey[source]
Added in version 0.5.
An elliptic curve private key for use with an algorithm such as ECDSA.
exchange(algorithm, peer_public_key)[source]
Added in version 1.1.
Performs a key exchange operation using the provided algorithm with
the peer’s public key.
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.
Parameters:
algorithm – The key exchange algorithm, currently only
ECDH
is
supported.
peer_public_key (EllipticCurvePublicKey) – The public key for the
peer.
Returns bytes:
A shared key.
Added in version 1.5.
Sign one block of data which can be verified later by others using the
public key.
Parameters:
data (bytes-like) – The message string to sign.
signature_algorithm – An instance of
EllipticCurveSignatureAlgorithm
, such as ECDSA
.
Return bytes:
The signature as a bytes
object, whose contents are
DER encoded as described in RFC 3279. This can be decoded using
decode_dss_signature()
,
which returns the decoded tuple (r, s)
.
private_bytes(encoding, format, encryption_algorithm)[source]
Allows serialization of the key to bytes. Encoding (
PEM
or
DER
),
format (
TraditionalOpenSSL
,
OpenSSH
PKCS8
)
and encryption algorithm (such as
BestAvailableEncryption
or NoEncryption
)
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.
class cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey[source]
Added in version 0.5.
An elliptic curve public key.
curve
Type:
EllipticCurve
The elliptic curve for this key.
public_bytes(encoding, format)[source]
Allows serialization of the key data to bytes. When encoding the public
key the encodings (
PEM
,
DER
) and
format (
SubjectPublicKeyInfo
)
are chosen to define the exact serialization. When encoding the point
the encoding
should be used with the formats (
UncompressedPoint
CompressedPoint
Parameters:
encoding – A value from the
Encoding
enum.
format – A value from the
PublicFormat
enum.
Return bytes:
Serialized data.
signature (bytes-like) – The DER-encoded signature to verify.
A raw signature may be DER-encoded by splitting it into the r
and s
components and passing them into
encode_dss_signature()
.
data (bytes-like) – The message string that was signed.
signature_algorithm – An instance of
EllipticCurveSignatureAlgorithm
.
Returns:
Raises:
cryptography.exceptions.InvalidSignature – If the signature does
not validate.
Decodes a byte string as described in SEC 1 v2.0 section 2.3.3 and
returns an EllipticCurvePublicKey
. This class method supports
compressed points.
Parameters:
curve – An
EllipticCurve
instance.
data (bytes) – The serialized point byte string.
Returns:
An EllipticCurvePublicKey
instance.
Raises:
ValueError – Raised when an invalid point is supplied.
TypeError – Raised when curve is not an
EllipticCurve
.
Serialization
This sample demonstrates how to generate a private key and serialize it.
>>> from cryptography.hazmat.primitives import serialization
>>> from cryptography.hazmat.primitives.asymmetric import ec
>>> private_key = ec.generate_private_key(ec.SECP384R1())
>>> serialized_private = private_key.private_bytes(
... encoding=serialization.Encoding.PEM,
... format=serialization.PrivateFormat.PKCS8,
... encryption_algorithm=serialization.BestAvailableEncryption(b'testpassword')
... )
>>> serialized_private.splitlines()[0]
b'-----BEGIN ENCRYPTED PRIVATE KEY-----'
You can also serialize the key without a password, by relying on
NoEncryption
.
The public key is serialized as follows:
>>> public_key = private_key.public_key()
>>> serialized_public = public_key.public_bytes(
... encoding=serialization.Encoding.PEM,
... format=serialization.PublicFormat.SubjectPublicKeyInfo
... )
>>> serialized_public.splitlines()[0]
b'-----BEGIN PUBLIC KEY-----'
This is the part that you would normally share with the rest of the world.
Key loading
This extends the sample in the previous section, assuming that the variables
serialized_private
and serialized_public
contain the respective keys
in PEM format.
>>> loaded_public_key = serialization.load_pem_public_key(
... serialized_public,
... )
>>> loaded_private_key = serialization.load_pem_private_key(
... serialized_private,
... # or password=None, if in plain text
... password=b'testpassword',
... )
cryptography.hazmat.primitives.asymmetric.ec.get_curve_for_oid(oid)[source]
Added in version 2.6.
A function that takes an ObjectIdentifier
and returns the associated elliptic curve class.
Parameters:
oid – An instance of
ObjectIdentifier
.
Returns:
The matching elliptic curve class. The returned class conforms
to the EllipticCurve
interface.
Raises:
LookupError – Raised if no elliptic curve is found that matches
the provided object identifier.