diff options
Diffstat (limited to 'docs/hazmat/primitives/asymmetric/rsa.rst')
| -rw-r--r-- | docs/hazmat/primitives/asymmetric/rsa.rst | 307 |
1 files changed, 172 insertions, 135 deletions
diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 3b5b677b..dab90964 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -19,11 +19,12 @@ mathematical properties`_. .. versionadded:: 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, currently ``1024`` and below are considered - breakable, and ``2048`` or ``4096`` are reasonable default key sizes for + ``key_size`` describes how many :term:`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, ``65537`` should almost always be used. + of the key generation will be. Unless you have a specific reason to do + otherwise, you should always `use 65537`_. .. doctest:: @@ -39,12 +40,12 @@ mathematical properties`_. Usually one of the small Fermat primes 3, 5, 17, 257, 65537. If in doubt you should `use 65537`_. - :param int key_size: The length of the modulus in bits. For keys + :param int key_size: The length of the modulus in :term:`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: A backend which provides + :param backend: A backend which implements :class:`~cryptography.hazmat.backends.interfaces.RSABackend`. :return: An instance of @@ -63,6 +64,7 @@ markers), you can load it: .. code-block:: pycon + >>> from cryptography.hazmat.backends import default_backend >>> from cryptography.hazmat.primitives import serialization >>> with open("path/to/key.pem", "rb") as key_file: @@ -98,7 +100,7 @@ to serialize the key. ... encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword') ... ) >>> pem.splitlines()[0] - '-----BEGIN ENCRYPTED PRIVATE KEY-----' + b'-----BEGIN ENCRYPTED PRIVATE KEY-----' It is also possible to serialize without encryption using :class:`~cryptography.hazmat.primitives.serialization.NoEncryption`. @@ -111,12 +113,10 @@ It is also possible to serialize without encryption using ... encryption_algorithm=serialization.NoEncryption() ... ) >>> pem.splitlines()[0] - '-----BEGIN RSA PRIVATE KEY-----' + b'-----BEGIN RSA PRIVATE KEY-----' -Similarly, if your public key implements -:class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKeyWithSerialization` -interface you can use -:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKeyWithSerialization.public_bytes` +For public keys you can use +:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey.public_bytes` to serialize the key. .. doctest:: @@ -128,7 +128,7 @@ to serialize the key. ... format=serialization.PublicFormat.SubjectPublicKeyInfo ... ) >>> pem.splitlines()[0] - '-----BEGIN PUBLIC KEY-----' + b'-----BEGIN PUBLIC KEY-----' Signing ~~~~~~~ @@ -143,17 +143,15 @@ secure hash function and padding: >>> from cryptography.hazmat.primitives import hashes >>> from cryptography.hazmat.primitives.asymmetric import padding - - >>> signer = private_key.signer( + >>> 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() ... ) - >>> message = b"A message I want to sign" - >>> signer.update(message) - >>> signature = signer.finalize() Valid paddings for signatures are :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` and @@ -161,31 +159,78 @@ Valid paddings for signatures are 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 +:class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed`. + +.. doctest:: + + >>> 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, and a signature, you can -check that the public key genuinely was used to sign that specific message. You -also need to know which signing algorithm was used: +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 +:func:`~cryptography.hazmat.primitives.serialization.load_pem_public_key`, +:func:`~cryptography.hazmat.primitives.serialization.load_der_public_key`, +:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers.public_key` +, or +:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.public_key`. .. doctest:: >>> public_key = private_key.public_key() - >>> verifier = public_key.verifier( + >>> public_key.verify( ... signature, + ... message, ... padding.PSS( ... mgf=padding.MGF1(hashes.SHA256()), ... salt_length=padding.PSS.MAX_LENGTH ... ), ... hashes.SHA256() ... ) - >>> verifier.update(message) - >>> verifier.verify() If the signature does not match, ``verify()`` will raise an :class:`~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 +:class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed`. + +.. doctest:: + + >>> 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 ~~~~~~~~~~ @@ -202,8 +247,8 @@ options. Here's an example using a secure padding and hash function: >>> ciphertext = public_key.encrypt( ... message, ... padding.OAEP( - ... mgf=padding.MGF1(algorithm=hashes.SHA1()), - ... algorithm=hashes.SHA1(), + ... mgf=padding.MGF1(algorithm=hashes.SHA256()), + ... algorithm=hashes.SHA256(), ... label=None ... ) ... ) @@ -225,8 +270,8 @@ 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.SHA1()), - ... algorithm=hashes.SHA1(), + ... mgf=padding.MGF1(algorithm=hashes.SHA256()), + ... algorithm=hashes.SHA256(), ... label=None ... ) ... ) @@ -267,7 +312,7 @@ Padding Pass this attribute to ``salt_length`` to get the maximum salt length available. -.. class:: OAEP(mgf, label) +.. class:: OAEP(mgf, algorithm, label) .. versionadded:: 0.4 @@ -279,6 +324,9 @@ Padding :param mgf: A mask generation function object. At this time the only supported MGF is :class:`MGF1`. + :param algorithm: An instance of + :class:`~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`` or ``b""``, which are equivalent. @@ -294,6 +342,20 @@ Padding :class:`OAEP` should be preferred for encryption and :class:`PSS` should be preferred for signatures. + +.. function:: calculate_max_pss_salt_length(key, hash_algorithm) + + .. versionadded:: 1.5 + + :param key: An RSA public or private key. + :param hash_algorithm: A + :class:`cryptography.hazmat.primitives.hashes.HashAlgorithm`. + :returns int: The computed salt length. + + Computes the length of the salt that :class:`PSS` will use if + :data:`PSS.MAX_LENGTH` is used. + + Mask generation functions ------------------------- @@ -305,11 +367,10 @@ Mask generation functions Removed the deprecated ``salt_length`` parameter. MGF1 (Mask Generation Function 1) is used as the mask generation function - in :class:`PSS` padding. It takes a hash algorithm and a salt length. + in :class:`PSS` and :class:`OAEP` padding. It takes a hash algorithm. - :param algorithm: An instance of a - :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` - provider. + :param algorithm: An instance of + :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`. Numbers ~~~~~~~ @@ -340,13 +401,11 @@ is unavailable. .. method:: public_key(backend) - :param backend: A - :class:`~cryptography.hazmat.backends.interfaces.RSABackend` - provider. + :param backend: An instance of + :class:`~cryptography.hazmat.backends.interfaces.RSABackend`. - :returns: A new instance of a - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey` - provider. + :returns: A new instance of + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`. .. class:: RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, public_numbers) @@ -409,13 +468,11 @@ is unavailable. .. method:: private_key(backend) - :param backend: A new instance of a - :class:`~cryptography.hazmat.backends.interfaces.RSABackend` - provider. + :param backend: A new instance of + :class:`~cryptography.hazmat.backends.interfaces.RSABackend`. - :returns: A - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` - provider. + :returns: An instance of + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`. Handling partial RSA private keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -423,7 +480,7 @@ 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 +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 @@ -440,15 +497,15 @@ this without having to do the math themselves. .. versionadded:: 0.4 - Computes the ``dmp1`` parameter from the RSA private exponent and prime - ``p``. + Computes the ``dmp1`` parameter from the RSA private exponent (``d``) and + prime ``p``. .. function:: rsa_crt_dmq1(private_exponent, q) .. versionadded:: 0.4 - Computes the ``dmq1`` parameter from the RSA private exponent and prime - ``q``. + Computes the ``dmq1`` parameter from the RSA private exponent (``d``) and + prime ``q``. .. function:: rsa_recover_prime_factors(n, e, d) @@ -460,7 +517,9 @@ this without having to do the math themselves. .. note:: When recovering prime factors this algorithm will always return ``p`` - and ``q`` such that ``p < q``. + 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)`` @@ -472,24 +531,9 @@ Key interfaces .. versionadded:: 0.2 - An `RSA`_ private key. - - .. method:: signer(padding, algorithm) - - .. versionadded:: 0.3 - - Sign data which can be verified later by others using the public key. - - :param padding: An instance of a - :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding` - provider. - - :param algorithm: An instance of a - :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` - provider. - - :returns: - :class:`~cryptography.hazmat.primitives.asymmetric.AsymmetricSignatureContext` + An `RSA`_ private key. An RSA private key that is not an + :term:`opaque key` also implements :class:`RSAPrivateKeyWithSerialization` + to provide serialization methods. .. method:: decrypt(ciphertext, padding) @@ -499,9 +543,8 @@ Key interfaces :param bytes ciphertext: The ciphertext to decrypt. - :param padding: An instance of an - :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding` - provider. + :param padding: An instance of + :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`. :return bytes: Decrypted data. @@ -517,29 +560,36 @@ Key interfaces The bit length of the modulus. + .. method:: sign(data, padding, algorithm) -.. class:: RSAPrivateKeyWithNumbers + .. versionadded:: 1.4 + .. versionchanged:: 1.6 + :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed` + can now be used as an ``algorithm``. - .. versionadded:: 0.5 + Sign one block of data which can be verified later by others using the + public key. - Extends :class:`RSAPrivateKey`. + :param bytes data: The message string to sign. - .. method:: private_numbers() + :param padding: An instance of + :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`. - Create a - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` - object. + :param algorithm: An instance of + :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` or + :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed` + if the ``data`` you want to sign has already been hashed. - :returns: An - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` - instance. + :return bytes: Signature. .. class:: RSAPrivateKeyWithSerialization .. versionadded:: 0.8 - Extends :class:`RSAPrivateKey`. + This interface contains additional methods relating to serialization. + Any object with this interface also has all the methods from + :class:`RSAPrivateKey`. .. method:: private_numbers() @@ -585,26 +635,6 @@ Key interfaces An `RSA`_ public key. - .. method:: verifier(signature, padding, algorithm) - - .. versionadded:: 0.3 - - Verify data was signed by the private key associated with this public - key. - - :param bytes signature: The signature to verify. - - :param padding: An instance of a - :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding` - provider. - - :param algorithm: An instance of a - :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` - provider. - - :returns: - :class:`~cryptography.hazmat.primitives.asymmetric.AsymmetricVerificationContext` - .. method:: encrypt(plaintext, padding) .. versionadded:: 0.4 @@ -613,9 +643,8 @@ Key interfaces :param bytes plaintext: The plaintext to encrypt. - :param padding: An instance of a - :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding` - provider. + :param padding: An instance of + :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`. :return bytes: Encrypted data. @@ -625,30 +654,6 @@ Key interfaces The bit length of the modulus. - -.. class:: RSAPublicKeyWithNumbers - - .. versionadded:: 0.5 - - Extends :class:`RSAPublicKey`. - - .. method:: public_numbers() - - Create a - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers` - object. - - :returns: An - :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers` - instance. - - -.. class:: RSAPublicKeyWithSerialization - - .. versionadded:: 0.8 - - Extends :class:`RSAPublicKey`. - .. method:: public_numbers() Create a @@ -678,14 +683,46 @@ Key interfaces :return bytes: Serialized key. + .. method:: verify(signature, data, padding, algorithm) + + .. versionadded:: 1.4 + .. versionchanged:: 1.6 + :class:`~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 + :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`. + + :param algorithm: An instance of + :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` or + :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed` + if the ``data`` you want to verify has already been hashed. + + :raises cryptography.exceptions.InvalidSignature: If the signature does + not validate. + + +.. class:: RSAPublicKeyWithSerialization + + .. versionadded:: 0.8 + + Alias for :class:`RSAPublicKey`. + .. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem) .. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography .. _`specific mathematical properties`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Key_generation -.. _`use 65537`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html -.. _`at least 2048`: http://www.ecrypt.eu.org/ecrypt2/documents/D.SPA.20.pdf +.. _`use 65537`: https://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html +.. _`at least 2048`: https://www.cosic.esat.kuleuven.be/ecrypt/ecrypt2/documents/D.SPA.20.pdf .. _`OpenPGP`: https://en.wikipedia.org/wiki/Pretty_Good_Privacy .. _`Chinese Remainder Theorem`: https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Using_the_Chinese_remainder_algorithm -.. _`security proof`: http://eprint.iacr.org/2001/062.pdf -.. _`recommended padding algorithm`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html -.. _`proven secure`: http://cseweb.ucsd.edu/~mihir/papers/oae.pdf +.. _`security proof`: https://eprint.iacr.org/2001/062.pdf +.. _`recommended padding algorithm`: https://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html +.. _`proven secure`: https://cseweb.ucsd.edu/~mihir/papers/oae.pdf |
