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.
RSA¶
RSA is a public-key algorithm for encrypting and signing messages.
Generation¶
Unlike symmetric cryptography, where the key is typically just a random series of bytes, RSA keys have a complex internal structure with specific mathematical properties.
-
cryptography.hazmat.primitives.asymmetric.rsa.
generate_private_key
(public_exponent, key_size, backend)[source]¶ New in version 0.5.
Generates a new RSA private key using the provided
backend
.key_size
describes how many bits long the key should be. Larger keys provide more security; currently1024
and below are considered breakable while2048
or4096
are reasonable default key sizes for new keys. Thepublic_exponent
indicates what one mathematical property of the key generation will be. Unless you have a specific reason to do otherwise, you should always use 65537.>>> from cryptography.hazmat.backends import default_backend >>> from cryptography.hazmat.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key( ... public_exponent=65537, ... key_size=2048, ... backend=default_backend() ... )
Parameters: - public_exponent (int) – The public exponent of the new key. Usually one of the small Fermat primes 3, 5, 17, 257, 65537. If in doubt you should use 65537.
- key_size (int) – The length of the modulus in bits. For keys generated in 2015 it is strongly recommended to be at least 2048 (See page 41). It must not be less than 512. Some backends may have additional limitations.
- backend – A backend which implements
RSABackend
.
Returns: An instance of
RSAPrivateKey
.Raises: cryptography.exceptions.UnsupportedAlgorithm – This is raised if the provided
backend
does not implementRSABackend
Key loading¶
If you already have an on-disk key in the PEM format (which are recognizable by
the distinctive -----BEGIN {format}-----
and -----END {format}-----
markers), you can load it:
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import serialization
>>> with open("path/to/key.pem", "rb") as key_file:
... private_key = serialization.load_pem_private_key(
... key_file.read(),
... password=None,
... backend=default_backend()
... )
Serialized keys may optionally be encrypted on disk using a password. In this
example we loaded an unencrypted key, and therefore we did not provide a
password. If the key is encrypted we can pass a bytes
object as the
password
argument.
There is also support for loading public keys in the SSH format
.
Key serialization¶
If you have a private key that you’ve loaded or generated which implements the
RSAPrivateKeyWithSerialization
interface you can use
private_bytes()
to serialize the key.
>>> from cryptography.hazmat.primitives import serialization
>>> pem = private_key.private_bytes(
... encoding=serialization.Encoding.PEM,
... format=serialization.PrivateFormat.PKCS8,
... encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword')
... )
>>> pem.splitlines()[0]
b'-----BEGIN ENCRYPTED PRIVATE KEY-----'
It is also possible to serialize without encryption using
NoEncryption
.
>>> pem = private_key.private_bytes(
... encoding=serialization.Encoding.PEM,
... format=serialization.PrivateFormat.TraditionalOpenSSL,
... encryption_algorithm=serialization.NoEncryption()
... )
>>> pem.splitlines()[0]
b'-----BEGIN RSA PRIVATE KEY-----'
For public keys you can use
public_bytes()
to serialize the key.
>>> from cryptography.hazmat.primitives import serialization
>>> public_key = private_key.public_key()
>>> pem = public_key.public_bytes(
... encoding=serialization.Encoding.PEM,
... format=serialization.PublicFormat.SubjectPublicKeyInfo
... )
>>> pem.splitlines()[0]
b'-----BEGIN PUBLIC KEY-----'
Signing¶
A private key can be used to sign a message. This allows anyone with the public
key to verify that the message was created by someone who possesses the
corresponding private key. RSA signatures require a specific hash function, and
padding to be used. Here is an example of signing message
using RSA, with a
secure hash function and padding:
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import padding
>>> message = b"A message I want to sign"
>>> signature = private_key.sign(
... message,
... padding.PSS(
... mgf=padding.MGF1(hashes.SHA256()),
... salt_length=padding.PSS.MAX_LENGTH
... ),
... hashes.SHA256()
... )
Valid paddings for signatures are
PSS
and
PKCS1v15
. PSS
is the recommended choice for any new protocols or applications, PKCS1v15
should only be used to support legacy protocols.
If your data is too large to be passed in a single call, you can hash it
separately and pass that value using
Prehashed
.
>>> from cryptography.hazmat.primitives.asymmetric import utils
>>> chosen_hash = hashes.SHA256()
>>> hasher = hashes.Hash(chosen_hash, default_backend())
>>> hasher.update(b"data & ")
>>> hasher.update(b"more data")
>>> digest = hasher.finalize()
>>> sig = private_key.sign(
... digest,
... padding.PSS(
... mgf=padding.MGF1(hashes.SHA256()),
... salt_length=padding.PSS.MAX_LENGTH
... ),
... utils.Prehashed(chosen_hash)
... )
Verification¶
The previous section describes what to do if you have a private key and want to
sign something. If you have a public key, a message, a signature, and the
signing algorithm that was used you can check that the private key associated
with a given public key was used to sign that specific message. You can obtain
a public key to use in verification using
load_pem_public_key()
,
load_der_public_key()
,
public_key()
, or
public_key()
.
>>> public_key = private_key.public_key()
>>> public_key.verify(
... signature,
... message,
... padding.PSS(
... mgf=padding.MGF1(hashes.SHA256()),
... salt_length=padding.PSS.MAX_LENGTH
... ),
... hashes.SHA256()
... )
If the signature does not match, verify()
will raise an
InvalidSignature
exception.
If your data is too large to be passed in a single call, you can hash it
separately and pass that value using
Prehashed
.
>>> chosen_hash = hashes.SHA256()
>>> hasher = hashes.Hash(chosen_hash, default_backend())
>>> hasher.update(b"data & ")
>>> hasher.update(b"more data")
>>> digest = hasher.finalize()
>>> public_key.verify(
... sig,
... digest,
... padding.PSS(
... mgf=padding.MGF1(hashes.SHA256()),
... salt_length=padding.PSS.MAX_LENGTH
... ),
... utils.Prehashed(chosen_hash)
... )
Encryption¶
RSA encryption is interesting because encryption is performed using the public key, meaning anyone can encrypt data. The data is then decrypted using the private key.
Like signatures, RSA supports encryption with several different padding options. Here’s an example using a secure padding and hash function:
>>> message = b"encrypted data"
>>> ciphertext = public_key.encrypt(
... message,
... padding.OAEP(
... mgf=padding.MGF1(algorithm=hashes.SHA256()),
... algorithm=hashes.SHA256(),
... label=None
... )
... )
Valid paddings for encryption are
OAEP
and
PKCS1v15
. OAEP
is the recommended choice for any new protocols or applications, PKCS1v15
should only be used to support legacy protocols.
Decryption¶
Once you have an encrypted message, it can be decrypted using the private key:
>>> plaintext = private_key.decrypt(
... ciphertext,
... padding.OAEP(
... mgf=padding.MGF1(algorithm=hashes.SHA256()),
... algorithm=hashes.SHA256(),
... label=None
... )
... )
>>> plaintext == message
True
Padding¶
-
class
cryptography.hazmat.primitives.asymmetric.padding.
AsymmetricPadding
[source]¶ New in version 0.2.
-
name
¶
-
-
class
cryptography.hazmat.primitives.asymmetric.padding.
PSS
(mgf, salt_length)[source]¶ New in version 0.3.
Changed in version 0.4: Added
salt_length
parameter.PSS (Probabilistic Signature Scheme) is a signature scheme defined in RFC 3447. It is more complex than PKCS1 but possesses a security proof. This is the recommended padding algorithm for RSA signatures. It cannot be used with RSA encryption.
Parameters: -
MAX_LENGTH
¶ Pass this attribute to
salt_length
to get the maximum salt length available.
-
-
class
cryptography.hazmat.primitives.asymmetric.padding.
OAEP
(mgf, algorithm, label)[source]¶ New in version 0.4.
OAEP (Optimal Asymmetric Encryption Padding) is a padding scheme defined in RFC 3447. It provides probabilistic encryption and is proven secure against several attack types. This is the recommended padding algorithm for RSA encryption. It cannot be used with RSA signing.
Parameters: - mgf – A mask generation function object. At this time the only
supported MGF is
MGF1
. - algorithm – An instance of
HashAlgorithm
. - label (bytes) – A label to apply. This is a rarely used field and
should typically be set to
None
orb""
, which are equivalent.
- mgf – A mask generation function object. At this time the only
supported MGF is
-
class
cryptography.hazmat.primitives.asymmetric.padding.
PKCS1v15
[source]¶ New in version 0.3.
PKCS1 v1.5 (also known as simply PKCS1) is a simple padding scheme developed for use with RSA keys. It is defined in RFC 3447. This padding can be used for signing and encryption.
It is not recommended that
PKCS1v15
be used for new applications,OAEP
should be preferred for encryption andPSS
should be preferred for signatures.
-
cryptography.hazmat.primitives.asymmetric.padding.
calculate_max_pss_salt_length
(key, hash_algorithm)[source]¶ New in version 1.5.
Parameters: - key – An RSA public or private key.
- hash_algorithm – A
cryptography.hazmat.primitives.hashes.HashAlgorithm
.
Returns int: The computed salt length.
Computes the length of the salt that
PSS
will use ifPSS.MAX_LENGTH
is used.
Mask generation functions¶
-
class
cryptography.hazmat.primitives.asymmetric.padding.
MGF1
(algorithm)[source]¶ New in version 0.3.
Changed in version 0.6: Removed the deprecated
salt_length
parameter.MGF1 (Mask Generation Function 1) is used as the mask generation function in
PSS
andOAEP
padding. It takes a hash algorithm.Parameters: algorithm – An instance of HashAlgorithm
.
Numbers¶
These classes hold the constituent components of an RSA key. They are useful only when more traditional Key Serialization is unavailable.
-
class
cryptography.hazmat.primitives.asymmetric.rsa.
RSAPublicNumbers
(e, n)[source]¶ New in version 0.5.
The collection of integers that make up an RSA public key.
-
public_key
(backend)[source]¶ Parameters: backend – An instance of RSABackend
.Returns: A new instance of RSAPublicKey
.
-
-
class
cryptography.hazmat.primitives.asymmetric.rsa.
RSAPrivateNumbers
(p, q, d, dmp1, dmq1, iqmp, public_numbers)[source]¶ New in version 0.5.
The collection of integers that make up an RSA private key.
Warning
With the exception of the integers contained in the
RSAPublicNumbers
all attributes of this class must be kept secret. Revealing them will compromise the security of any cryptographic operations performed with a key loaded from them.-
public_numbers
¶ Type: RSAPublicNumbers
The
RSAPublicNumbers
which makes up the RSA public key associated with this RSA private key.
-
dmp1
¶ Type: int A Chinese remainder theorem coefficient used to speed up RSA operations. Calculated as: d mod (p-1)
-
dmq1
¶ Type: int A Chinese remainder theorem coefficient used to speed up RSA operations. Calculated as: d mod (q-1)
-
iqmp
¶ Type: int A Chinese remainder theorem coefficient used to speed up RSA operations. Calculated as: q-1 mod p
-
private_key
(backend)[source]¶ Parameters: backend – A new instance of RSABackend
.Returns: An instance of RSAPrivateKey
.
-
Handling partial RSA private keys¶
If you are trying to load RSA private keys yourself you may find that not all
parameters required by RSAPrivateNumbers
are available. In particular the
Chinese Remainder Theorem (CRT) values dmp1
, dmq1
, iqmp
may be
missing or present in a different form. For example, OpenPGP does not include
the iqmp
, dmp1
or dmq1
parameters.
The following functions are provided for users who want to work with keys like this without having to do the math themselves.
-
cryptography.hazmat.primitives.asymmetric.rsa.
rsa_crt_iqmp
(p, q)[source]¶ New in version 0.4.
Computes the
iqmp
(also known asqInv
) parameter from the RSA primesp
andq
.
-
cryptography.hazmat.primitives.asymmetric.rsa.
rsa_crt_dmp1
(private_exponent, p)[source]¶ New in version 0.4.
Computes the
dmp1
parameter from the RSA private exponent (d
) and primep
.
-
cryptography.hazmat.primitives.asymmetric.rsa.
rsa_crt_dmq1
(private_exponent, q)[source]¶ New in version 0.4.
Computes the
dmq1
parameter from the RSA private exponent (d
) and primeq
.
-
cryptography.hazmat.primitives.asymmetric.rsa.
rsa_recover_prime_factors
(n, e, d)[source]¶ New in version 0.8.
Computes the prime factors
(p, q)
given the modulus, public exponent, and private exponent.Note
When recovering prime factors this algorithm will always return
p
andq
such thatp > q
. Note: before 1.5, this function always returnedp
andq
such thatp < q
. It was changed because libraries commonly requirep > q
.Returns: A tuple (p, q)
Key interfaces¶
-
class
cryptography.hazmat.primitives.asymmetric.rsa.
RSAPrivateKey
[source]¶ New in version 0.2.
An RSA private key. An RSA private key that is not an opaque key also implements
RSAPrivateKeyWithSerialization
to provide serialization methods.-
decrypt
(ciphertext, padding)[source]¶ New in version 0.4.
Decrypt data that was encrypted with the public key.
Parameters: - ciphertext (bytes) – The ciphertext to decrypt.
- padding – An instance of
AsymmetricPadding
.
Return bytes: Decrypted data.
-
public_key
()[source]¶ Returns: RSAPublicKey
An RSA public key object corresponding to the values of the private key.
-
sign
(data, padding, algorithm)[source]¶ New in version 1.4.
Changed in version 1.6:
Prehashed
can now be used as analgorithm
.Sign one block of data which can be verified later by others using the public key.
Parameters: - data (bytes) – The message string to sign.
- padding – An instance of
AsymmetricPadding
. - algorithm – An instance of
HashAlgorithm
orPrehashed
if thedata
you want to sign has already been hashed.
Return bytes: Signature.
-
-
class
cryptography.hazmat.primitives.asymmetric.rsa.
RSAPrivateKeyWithSerialization
[source]¶ New in version 0.8.
This interface contains additional methods relating to serialization. Any object with this interface also has all the methods from
RSAPrivateKey
.-
private_numbers
()[source]¶ Create a
RSAPrivateNumbers
object.Returns: An RSAPrivateNumbers
instance.
-
private_bytes
(encoding, format, encryption_algorithm)[source]¶ Allows serialization of the key to bytes. Encoding (
PEM
orDER
), format (TraditionalOpenSSL
orPKCS8
) 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.rsa.
RSAPublicKey
[source]¶ New in version 0.2.
An RSA public key.
-
encrypt
(plaintext, padding)[source]¶ New in version 0.4.
Encrypt data with the public key.
Parameters: - plaintext (bytes) – The plaintext to encrypt.
- padding – An instance of
AsymmetricPadding
.
Return bytes: Encrypted data.
-
public_numbers
()[source]¶ Create a
RSAPublicNumbers
object.Returns: An RSAPublicNumbers
instance.
-
public_bytes
(encoding, format)[source]¶ Allows serialization of the key to bytes. Encoding (
PEM
orDER
) and format (SubjectPublicKeyInfo
orPKCS1
) 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
-
verify
(signature, data, padding, algorithm)[source]¶ New in version 1.4.
Changed in version 1.6:
Prehashed
can now be used as analgorithm
.Verify one block of data was signed by the private key associated with this public key.
Parameters: - signature (bytes) – The signature to verify.
- data (bytes) – The message string that was signed.
- padding – An instance of
AsymmetricPadding
. - algorithm – An instance of
HashAlgorithm
orPrehashed
if thedata
you want to verify has already been hashed.
Raises: cryptography.exceptions.InvalidSignature – If the signature does not validate.
-
-
class
cryptography.hazmat.primitives.asymmetric.rsa.
RSAPublicKeyWithSerialization
¶ New in version 0.8.
Alias for
RSAPublicKey
.