cryptography.hazmat.primitives.asymmetric.rsa
RSA is a public-key algorithm for encrypting and signing messages.
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.
generate_private_key(public_exponent, key_size, backend=None)
0.5
3.0
Tightened restrictions on public_exponent
.
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; currently 1024
and below are considered breakable while 2048
or 4096
are reasonable default key sizes for new keys. The public_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.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key( ... public_exponent=65537, ... key_size=2048, ... )
- param int public_exponent
The public exponent of the new key. Either 65537 or 3 (for legacy purposes). Almost everyone should use 65537.
- param int key_size
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.- param backend
An optional backend which implements
~cryptography.hazmat.backends.interfaces.RSABackend
.- return
An instance of
~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey
.- raises cryptography.exceptions.UnsupportedAlgorithm
This is raised if the provided
backend
does not implement~cryptography.hazmat.backends.interfaces.RSABackend
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.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,
... )
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
<cryptography.hazmat.primitives.serialization.load_ssh_public_key>
.
If you have a private key that you've loaded you can use ~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.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 ~cryptography.hazmat.primitives.serialization.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 ~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey.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-----'
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 ~cryptography.hazmat.primitives.asymmetric.padding.PSS
and ~cryptography.hazmat.primitives.asymmetric.padding.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 ~cryptography.hazmat.primitives.asymmetric.utils.Prehashed
.
>>> from cryptography.hazmat.primitives.asymmetric import utils >>> chosen_hash = hashes.SHA256() >>> hasher = hashes.Hash(chosen_hash) >>> 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) ... )
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 ~cryptography.hazmat.primitives.serialization.load_pem_public_key
, ~cryptography.hazmat.primitives.serialization.load_der_public_key
, ~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers.public_key
, or ~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.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 ~cryptography.exceptions.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 ~cryptography.hazmat.primitives.asymmetric.utils.Prehashed
.
>>> chosen_hash = hashes.SHA256() >>> hasher = hashes.Hash(chosen_hash) >>> 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) ... )
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 ~cryptography.hazmat.primitives.asymmetric.padding.OAEP
and ~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15
. OAEP
is the recommended choice for any new protocols or applications, PKCS1v15
should only be used to support legacy protocols.
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
cryptography.hazmat.primitives.asymmetric.padding
0.2
name
0.3
0.4 Added salt_length
parameter.
PSS (Probabilistic Signature Scheme) is a signature scheme defined in 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.
- param mgf
A mask generation function object. At this time the only supported MGF is
MGF1
.- param int salt_length
The length of the salt. It is recommended that this be set to
PSS.MAX_LENGTH
.
MAX_LENGTH
Pass this attribute to salt_length
to get the maximum salt length available.
0.4
OAEP (Optimal Asymmetric Encryption Padding) is a padding scheme defined in 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.
- param mgf
A mask generation function object. At this time the only supported MGF is
MGF1
.- param algorithm
An instance of
~cryptography.hazmat.primitives.hashes.HashAlgorithm
.- param bytes label
A label to apply. This is a rarely used field and should typically be set to
None
orb""
, which are equivalent.
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 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 and PSS
should be preferred for signatures.
Warning
Our implementation of PKCS1 v1.5 decryption is not constant time. See /limitations
for details.
calculate_max_pss_salt_length(key, hash_algorithm)
1.5
- param key
An RSA public or private key.
- param hash_algorithm
A
cryptography.hazmat.primitives.hashes.HashAlgorithm
.- returns int
The computed salt length.
Computes the length of the salt that PSS
will use if PSS.MAX_LENGTH
is used.
0.3
0.6 Removed the deprecated salt_length
parameter.
MGF1 (Mask Generation Function 1) is used as the mask generation function in PSS
and OAEP
padding. It takes a hash algorithm.
- param algorithm
An instance of
~cryptography.hazmat.primitives.hashes.HashAlgorithm
.
cryptography.hazmat.primitives.asymmetric.rsa
These classes hold the constituent components of an RSA key. They are useful only when more traditional /hazmat/primitives/asymmetric/serialization
is unavailable.
0.5
The collection of integers that make up an RSA public key.
n
- type
int
The public modulus.
e
- type
int
The public exponent.
public_key(backend=None)
- param backend
An optional instance of
~cryptography.hazmat.backends.interfaces.RSABackend
.- returns
A new instance of
~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey
.
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
~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers
The RSAPublicNumbers
which makes up the RSA public key associated with this RSA private key.
p
- type
int
p
, one of the two primes composing n
.
q
- type
int
q
, one of the two primes composing n
.
d
- type
int
The private exponent.
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=None)
- param backend
An optional instance of
~cryptography.hazmat.backends.interfaces.RSABackend
.- returns
An instance of
~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey
.
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.
rsa_crt_iqmp(p, q)
0.4
Computes the iqmp
(also known as qInv
) parameter from the RSA primes p
and q
.
rsa_crt_dmp1(private_exponent, p)
0.4
Computes the dmp1
parameter from the RSA private exponent (d
) and prime p
.
rsa_crt_dmq1(private_exponent, q)
0.4
Computes the dmq1
parameter from the RSA private exponent (d
) and prime q
.
rsa_recover_prime_factors(n, e, d)
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
and q
such that p > q
. Note: before 1.5, this function always returned p
and q
such that p < q
. It was changed because libraries commonly require p > q
.
- return
A tuple
(p, q)
0.2
An RSA private key.
decrypt(ciphertext, padding)
0.4
Decrypt data that was encrypted with the public key.
- param bytes ciphertext
The ciphertext to decrypt.
- param padding
An instance of
~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding
.- return bytes
Decrypted data.
public_key()
- return
~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey
An RSA public key object corresponding to the values of the private key.
key_size
- type
int
The bit length of the modulus.
sign(data, padding, algorithm)
1.4
1.6 ~cryptography.hazmat.primitives.asymmetric.utils.Prehashed
can now be used as an algorithm
.
Sign one block of data which can be verified later by others using the public key.
- param bytes data
The message string to sign.
- param padding
An instance of
~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding
.- param algorithm
An instance of
~cryptography.hazmat.primitives.hashes.HashAlgorithm
or~cryptography.hazmat.primitives.asymmetric.utils.Prehashed
if thedata
you want to sign has already been hashed.- return bytes
Signature.
private_numbers()
Create a ~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers
object.
- returns
An
~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers
instance.
private_bytes(encoding, format, encryption_algorithm)
Allows serialization of the key to bytes. Encoding ( ~cryptography.hazmat.primitives.serialization.Encoding.PEM
or ~cryptography.hazmat.primitives.serialization.Encoding.DER
), format ( ~cryptography.hazmat.primitives.serialization.PrivateFormat.TraditionalOpenSSL
, ~cryptography.hazmat.primitives.serialization.PrivateFormat.OpenSSH
or ~cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8
) and encryption algorithm (such as ~cryptography.hazmat.primitives.serialization.BestAvailableEncryption
or ~cryptography.hazmat.primitives.serialization.NoEncryption
) are chosen to define the exact serialization.
- param encoding
A value from the
~cryptography.hazmat.primitives.serialization.Encoding
enum.- param format
A value from the
~cryptography.hazmat.primitives.serialization.PrivateFormat
enum.- param encryption_algorithm
An instance of an object conforming to the
~cryptography.hazmat.primitives.serialization.KeySerializationEncryption
interface.- return bytes
Serialized key.
0.8
Alias for RSAPrivateKey
.
0.2
An RSA public key.
encrypt(plaintext, padding)
0.4
Encrypt data with the public key.
- param bytes plaintext
The plaintext to encrypt.
- param padding
An instance of
~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding
.- return bytes
Encrypted data.
- raises ValueError
The data could not be encrypted. One possible cause is if
data
is too large; RSA keys can only encrypt data that is smaller than the key size.
key_size
- type
int
The bit length of the modulus.
public_numbers()
Create a ~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers
object.
- returns
An
~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers
instance.
public_bytes(encoding, format)
Allows serialization of the key to bytes. Encoding ( ~cryptography.hazmat.primitives.serialization.Encoding.PEM
or ~cryptography.hazmat.primitives.serialization.Encoding.DER
) and format ( ~cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo
or ~cryptography.hazmat.primitives.serialization.PublicFormat.PKCS1
) are chosen to define the exact serialization.
- param encoding
A value from the
~cryptography.hazmat.primitives.serialization.Encoding
enum.- param format
A value from the
~cryptography.hazmat.primitives.serialization.PublicFormat
enum.- return bytes
Serialized key.
verify(signature, data, padding, algorithm)
1.4
1.6 ~cryptography.hazmat.primitives.asymmetric.utils.Prehashed
can now be used as an algorithm
.
Verify one block of data was signed by the private key associated with this public key.
- param bytes signature
The signature to verify.
- param bytes data
The message string that was signed.
- param padding
An instance of
~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding
.- param algorithm
An instance of
~cryptography.hazmat.primitives.hashes.HashAlgorithm
or~cryptography.hazmat.primitives.asymmetric.utils.Prehashed
if thedata
you want to verify has already been hashed.- raises cryptography.exceptions.InvalidSignature
If the signature does not validate.
recover_data_from_signature(signature, padding, algorithm)
3.3
Recovers the signed data from the signature. The data typically contains the digest of the original message string. The padding
and algorithm
parameters must match the ones used when the signature was created for the recovery to succeed.
The algorithm
parameter can also be set to None
to recover all the data present in the signature, without regard to its format or the hash algorithm used for its creation.
For ~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15
padding, this method returns the data after removing the padding layer. For standard signatures the data contains the full DigestInfo
structure. For non-standard signatures, any data can be returned, including zero-length data.
Normally you should use the ~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey.verify
function to validate the signature. But for some non-standard signature formats you may need to explicitly recover and validate the signed data. The following are some examples:
- Some old Thawte and Verisign timestamp certificates without
DigestInfo
. - Signed MD5/SHA1 hashes in TLS 1.1 or earlier (
4346
, section 4.7). - IKE version 1 signatures without
DigestInfo
(2409
, section 5.1).
- param bytes signature
The signature.
- param padding
An instance of
~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding
. Recovery is only supported with some of the padding types. (Currently only with~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15
).- param algorithm
An instance of
~cryptography.hazmat.primitives.hashes.HashAlgorithm
. Can beNone
to return the all the data present in the signature.- return bytes
The signed data.
- raises cryptography.exceptions.InvalidSignature
If the signature is invalid.
- raises cryptography.exceptions.UnsupportedAlgorithm
If signature data recovery is not supported with the provided
padding
type.
0.8
Alias for RSAPublicKey
.