• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. hazmat::
2
3RSA
4===
5
6.. module:: cryptography.hazmat.primitives.asymmetric.rsa
7
8`RSA`_ is a `public-key`_ algorithm for encrypting and signing messages.
9
10Generation
11~~~~~~~~~~
12
13Unlike symmetric cryptography, where the key is typically just a random series
14of bytes, RSA keys have a complex internal structure with `specific
15mathematical properties`_.
16
17.. function:: generate_private_key(public_exponent, key_size, backend)
18
19    .. versionadded:: 0.5
20
21    Generates a new RSA private key using the provided ``backend``.
22    ``key_size`` describes how many :term:`bits` long the key should be. Larger
23    keys provide more security; currently ``1024`` and below are considered
24    breakable while ``2048`` or ``4096`` are reasonable default key sizes for
25    new keys. The ``public_exponent`` indicates what one mathematical property
26    of the key generation will be. Unless you have a specific reason to do
27    otherwise, you should always `use 65537`_.
28
29    .. doctest::
30
31        >>> from cryptography.hazmat.backends import default_backend
32        >>> from cryptography.hazmat.primitives.asymmetric import rsa
33        >>> private_key = rsa.generate_private_key(
34        ...     public_exponent=65537,
35        ...     key_size=2048,
36        ...     backend=default_backend()
37        ... )
38
39    :param int public_exponent: The public exponent of the new key.
40        Usually one of the small Fermat primes 3, 5, 17, 257, 65537. If in
41        doubt you should `use 65537`_.
42
43    :param int key_size: The length of the modulus in :term:`bits`. For keys
44        generated in 2015 it is strongly recommended to be
45        `at least 2048`_ (See page 41). It must not be less than 512.
46        Some backends may have additional limitations.
47
48    :param backend: A backend which implements
49        :class:`~cryptography.hazmat.backends.interfaces.RSABackend`.
50
51    :return: An instance of
52        :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`.
53
54    :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if
55        the provided ``backend`` does not implement
56        :class:`~cryptography.hazmat.backends.interfaces.RSABackend`
57
58Key loading
59~~~~~~~~~~~
60
61If you already have an on-disk key in the PEM format (which are recognizable by
62the distinctive ``-----BEGIN {format}-----`` and ``-----END {format}-----``
63markers), you can load it:
64
65.. code-block:: pycon
66
67    >>> from cryptography.hazmat.backends import default_backend
68    >>> from cryptography.hazmat.primitives import serialization
69
70    >>> with open("path/to/key.pem", "rb") as key_file:
71    ...     private_key = serialization.load_pem_private_key(
72    ...         key_file.read(),
73    ...         password=None,
74    ...         backend=default_backend()
75    ...     )
76
77Serialized keys may optionally be encrypted on disk using a password. In this
78example we loaded an unencrypted key, and therefore we did not provide a
79password. If the key is encrypted we can pass a ``bytes`` object as the
80``password`` argument.
81
82There is also support for :func:`loading public keys in the SSH format
83<cryptography.hazmat.primitives.serialization.load_ssh_public_key>`.
84
85Key serialization
86~~~~~~~~~~~~~~~~~
87
88If you have a private key that you've loaded or generated which implements the
89:class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization`
90interface you can use
91:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.private_bytes`
92to serialize the key.
93
94.. doctest::
95
96    >>> from cryptography.hazmat.primitives import serialization
97    >>> pem = private_key.private_bytes(
98    ...    encoding=serialization.Encoding.PEM,
99    ...    format=serialization.PrivateFormat.PKCS8,
100    ...    encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword')
101    ... )
102    >>> pem.splitlines()[0]
103    b'-----BEGIN ENCRYPTED PRIVATE KEY-----'
104
105It is also possible to serialize without encryption using
106:class:`~cryptography.hazmat.primitives.serialization.NoEncryption`.
107
108.. doctest::
109
110    >>> pem = private_key.private_bytes(
111    ...    encoding=serialization.Encoding.PEM,
112    ...    format=serialization.PrivateFormat.TraditionalOpenSSL,
113    ...    encryption_algorithm=serialization.NoEncryption()
114    ... )
115    >>> pem.splitlines()[0]
116    b'-----BEGIN RSA PRIVATE KEY-----'
117
118For public keys you can use
119:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey.public_bytes`
120to serialize the key.
121
122.. doctest::
123
124    >>> from cryptography.hazmat.primitives import serialization
125    >>> public_key = private_key.public_key()
126    >>> pem = public_key.public_bytes(
127    ...    encoding=serialization.Encoding.PEM,
128    ...    format=serialization.PublicFormat.SubjectPublicKeyInfo
129    ... )
130    >>> pem.splitlines()[0]
131    b'-----BEGIN PUBLIC KEY-----'
132
133Signing
134~~~~~~~
135
136A private key can be used to sign a message. This allows anyone with the public
137key to verify that the message was created by someone who possesses the
138corresponding private key. RSA signatures require a specific hash function, and
139padding to be used. Here is an example of signing ``message`` using RSA, with a
140secure hash function and padding:
141
142.. doctest::
143
144    >>> from cryptography.hazmat.primitives import hashes
145    >>> from cryptography.hazmat.primitives.asymmetric import padding
146    >>> message = b"A message I want to sign"
147    >>> signature = private_key.sign(
148    ...     message,
149    ...     padding.PSS(
150    ...         mgf=padding.MGF1(hashes.SHA256()),
151    ...         salt_length=padding.PSS.MAX_LENGTH
152    ...     ),
153    ...     hashes.SHA256()
154    ... )
155
156Valid paddings for signatures are
157:class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` and
158:class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15`. ``PSS``
159is the recommended choice for any new protocols or applications, ``PKCS1v15``
160should only be used to support legacy protocols.
161
162If your data is too large to be passed in a single call, you can hash it
163separately and pass that value using
164:class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed`.
165
166.. doctest::
167
168    >>> from cryptography.hazmat.primitives.asymmetric import utils
169    >>> chosen_hash = hashes.SHA256()
170    >>> hasher = hashes.Hash(chosen_hash, default_backend())
171    >>> hasher.update(b"data & ")
172    >>> hasher.update(b"more data")
173    >>> digest = hasher.finalize()
174    >>> sig = private_key.sign(
175    ...     digest,
176    ...     padding.PSS(
177    ...         mgf=padding.MGF1(hashes.SHA256()),
178    ...         salt_length=padding.PSS.MAX_LENGTH
179    ...     ),
180    ...     utils.Prehashed(chosen_hash)
181    ... )
182
183Verification
184~~~~~~~~~~~~
185
186The previous section describes what to do if you have a private key and want to
187sign something. If you have a public key, a message, a signature, and the
188signing algorithm that was used you can check that the private key associated
189with a given public key was used to sign that specific message.  You can obtain
190a public key to use in verification using
191:func:`~cryptography.hazmat.primitives.serialization.load_pem_public_key`,
192:func:`~cryptography.hazmat.primitives.serialization.load_der_public_key`,
193:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers.public_key`
194, or
195:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.public_key`.
196
197.. doctest::
198
199    >>> public_key = private_key.public_key()
200    >>> public_key.verify(
201    ...     signature,
202    ...     message,
203    ...     padding.PSS(
204    ...         mgf=padding.MGF1(hashes.SHA256()),
205    ...         salt_length=padding.PSS.MAX_LENGTH
206    ...     ),
207    ...     hashes.SHA256()
208    ... )
209
210If the signature does not match, ``verify()`` will raise an
211:class:`~cryptography.exceptions.InvalidSignature` exception.
212
213If your data is too large to be passed in a single call, you can hash it
214separately and pass that value using
215:class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed`.
216
217.. doctest::
218
219    >>> chosen_hash = hashes.SHA256()
220    >>> hasher = hashes.Hash(chosen_hash, default_backend())
221    >>> hasher.update(b"data & ")
222    >>> hasher.update(b"more data")
223    >>> digest = hasher.finalize()
224    >>> public_key.verify(
225    ...     sig,
226    ...     digest,
227    ...     padding.PSS(
228    ...         mgf=padding.MGF1(hashes.SHA256()),
229    ...         salt_length=padding.PSS.MAX_LENGTH
230    ...     ),
231    ...     utils.Prehashed(chosen_hash)
232    ... )
233
234Encryption
235~~~~~~~~~~
236
237RSA encryption is interesting because encryption is performed using the
238**public** key, meaning anyone can encrypt data. The data is then decrypted
239using the **private** key.
240
241Like signatures, RSA supports encryption with several different padding
242options. Here's an example using a secure padding and hash function:
243
244.. doctest::
245
246    >>> message = b"encrypted data"
247    >>> ciphertext = public_key.encrypt(
248    ...     message,
249    ...     padding.OAEP(
250    ...         mgf=padding.MGF1(algorithm=hashes.SHA256()),
251    ...         algorithm=hashes.SHA256(),
252    ...         label=None
253    ...     )
254    ... )
255
256Valid paddings for encryption are
257:class:`~cryptography.hazmat.primitives.asymmetric.padding.OAEP` and
258:class:`~cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15`. ``OAEP``
259is the recommended choice for any new protocols or applications, ``PKCS1v15``
260should only be used to support legacy protocols.
261
262
263Decryption
264~~~~~~~~~~
265
266Once you have an encrypted message, it can be decrypted using the private key:
267
268.. doctest::
269
270    >>> plaintext = private_key.decrypt(
271    ...     ciphertext,
272    ...     padding.OAEP(
273    ...         mgf=padding.MGF1(algorithm=hashes.SHA256()),
274    ...         algorithm=hashes.SHA256(),
275    ...         label=None
276    ...     )
277    ... )
278    >>> plaintext == message
279    True
280
281Padding
282~~~~~~~
283
284.. module:: cryptography.hazmat.primitives.asymmetric.padding
285
286.. class:: AsymmetricPadding
287
288    .. versionadded:: 0.2
289
290    .. attribute:: name
291
292.. class:: PSS(mgf, salt_length)
293
294    .. versionadded:: 0.3
295
296    .. versionchanged:: 0.4
297        Added ``salt_length`` parameter.
298
299    PSS (Probabilistic Signature Scheme) is a signature scheme defined in
300    :rfc:`3447`. It is more complex than PKCS1 but possesses a `security proof`_.
301    This is the `recommended padding algorithm`_ for RSA signatures. It cannot
302    be used with RSA encryption.
303
304    :param mgf: A mask generation function object. At this time the only
305        supported MGF is :class:`MGF1`.
306
307    :param int salt_length: The length of the salt. It is recommended that this
308        be set to ``PSS.MAX_LENGTH``.
309
310    .. attribute:: MAX_LENGTH
311
312        Pass this attribute to ``salt_length`` to get the maximum salt length
313        available.
314
315.. class:: OAEP(mgf, algorithm, label)
316
317    .. versionadded:: 0.4
318
319    OAEP (Optimal Asymmetric Encryption Padding) is a padding scheme defined in
320    :rfc:`3447`. It provides probabilistic encryption and is `proven secure`_
321    against several attack types. This is the `recommended padding algorithm`_
322    for RSA encryption. It cannot be used with RSA signing.
323
324    :param mgf: A mask generation function object. At this time the only
325        supported MGF is :class:`MGF1`.
326
327    :param algorithm: An instance of
328        :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`.
329
330    :param bytes label: A label to apply. This is a rarely used field and
331        should typically be set to ``None`` or ``b""``, which are equivalent.
332
333.. class:: PKCS1v15()
334
335    .. versionadded:: 0.3
336
337    PKCS1 v1.5 (also known as simply PKCS1) is a simple padding scheme
338    developed for use with RSA keys. It is defined in :rfc:`3447`. This padding
339    can be used for signing and encryption.
340
341    It is not recommended that ``PKCS1v15`` be used for new applications,
342    :class:`OAEP` should be preferred for encryption and :class:`PSS` should be
343    preferred for signatures.
344
345
346.. function:: calculate_max_pss_salt_length(key, hash_algorithm)
347
348    .. versionadded:: 1.5
349
350    :param key: An RSA public or private key.
351    :param hash_algorithm: A
352        :class:`cryptography.hazmat.primitives.hashes.HashAlgorithm`.
353    :returns int: The computed salt length.
354
355    Computes the length of the salt that :class:`PSS` will use if
356    :data:`PSS.MAX_LENGTH` is used.
357
358
359Mask generation functions
360-------------------------
361
362.. class:: MGF1(algorithm)
363
364    .. versionadded:: 0.3
365
366    .. versionchanged:: 0.6
367        Removed the deprecated ``salt_length`` parameter.
368
369    MGF1 (Mask Generation Function 1) is used as the mask generation function
370    in :class:`PSS` and :class:`OAEP` padding. It takes a hash algorithm.
371
372    :param algorithm: An instance of
373        :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`.
374
375Numbers
376~~~~~~~
377
378.. currentmodule:: cryptography.hazmat.primitives.asymmetric.rsa
379
380These classes hold the constituent components of an RSA key. They are useful
381only when more traditional :doc:`/hazmat/primitives/asymmetric/serialization`
382is unavailable.
383
384.. class:: RSAPublicNumbers(e, n)
385
386    .. versionadded:: 0.5
387
388    The collection of integers that make up an RSA public key.
389
390    .. attribute:: n
391
392        :type: int
393
394        The public modulus.
395
396    .. attribute:: e
397
398        :type: int
399
400        The public exponent.
401
402    .. method:: public_key(backend)
403
404        :param backend: An instance of
405            :class:`~cryptography.hazmat.backends.interfaces.RSABackend`.
406
407        :returns: A new instance of
408            :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`.
409
410.. class:: RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, public_numbers)
411
412    .. versionadded:: 0.5
413
414    The collection of integers that make up an RSA private key.
415
416    .. warning::
417
418        With the exception of the integers contained in the
419        :class:`RSAPublicNumbers` all attributes of this class must be kept
420        secret. Revealing them will compromise the security of any
421        cryptographic operations performed with a key loaded from them.
422
423    .. attribute:: public_numbers
424
425        :type: :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers`
426
427        The :class:`RSAPublicNumbers` which makes up the RSA public key
428        associated with this RSA private key.
429
430    .. attribute:: p
431
432        :type: int
433
434        ``p``, one of the two primes composing ``n``.
435
436    .. attribute:: q
437
438        :type: int
439
440        ``q``, one of the two primes composing ``n``.
441
442    .. attribute:: d
443
444        :type: int
445
446        The private exponent.
447
448    .. attribute:: dmp1
449
450        :type: int
451
452        A `Chinese remainder theorem`_ coefficient used to speed up RSA
453        operations. Calculated as: d mod (p-1)
454
455    .. attribute:: dmq1
456
457        :type: int
458
459        A `Chinese remainder theorem`_ coefficient used to speed up RSA
460        operations. Calculated as: d mod (q-1)
461
462    .. attribute:: iqmp
463
464        :type: int
465
466        A `Chinese remainder theorem`_ coefficient used to speed up RSA
467        operations. Calculated as: q\ :sup:`-1` mod p
468
469    .. method:: private_key(backend)
470
471        :param backend: A new instance of
472            :class:`~cryptography.hazmat.backends.interfaces.RSABackend`.
473
474        :returns: An instance of
475            :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`.
476
477Handling partial RSA private keys
478~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
479
480If you are trying to load RSA private keys yourself you may find that not all
481parameters required by ``RSAPrivateNumbers`` are available. In particular the
482`Chinese Remainder Theorem`_ (CRT) values ``dmp1``, ``dmq1``, ``iqmp`` may be
483missing or present in a different form. For example, `OpenPGP`_ does not include
484the ``iqmp``, ``dmp1`` or ``dmq1`` parameters.
485
486The following functions are provided for users who want to work with keys like
487this without having to do the math themselves.
488
489.. function:: rsa_crt_iqmp(p, q)
490
491    .. versionadded:: 0.4
492
493    Computes the ``iqmp`` (also known as ``qInv``) parameter from the RSA
494    primes ``p`` and ``q``.
495
496.. function:: rsa_crt_dmp1(private_exponent, p)
497
498    .. versionadded:: 0.4
499
500    Computes the ``dmp1`` parameter from the RSA private exponent (``d``) and
501    prime ``p``.
502
503.. function:: rsa_crt_dmq1(private_exponent, q)
504
505    .. versionadded:: 0.4
506
507    Computes the ``dmq1`` parameter from the RSA private exponent (``d``) and
508    prime ``q``.
509
510.. function:: rsa_recover_prime_factors(n, e, d)
511
512    .. versionadded:: 0.8
513
514    Computes the prime factors ``(p, q)`` given the modulus, public exponent,
515    and private exponent.
516
517    .. note::
518
519        When recovering prime factors this algorithm will always return ``p``
520        and ``q`` such that ``p > q``. Note: before 1.5, this function always
521        returned ``p`` and ``q`` such that ``p < q``. It was changed because
522        libraries commonly require ``p > q``.
523
524    :return: A tuple ``(p, q)``
525
526
527Key interfaces
528~~~~~~~~~~~~~~
529
530.. class:: RSAPrivateKey
531
532    .. versionadded:: 0.2
533
534    An `RSA`_ private key. An RSA private key that is not an
535    :term:`opaque key` also implements :class:`RSAPrivateKeyWithSerialization`
536    to provide serialization methods.
537
538    .. method:: decrypt(ciphertext, padding)
539
540        .. versionadded:: 0.4
541
542        Decrypt data that was encrypted with the public key.
543
544        :param bytes ciphertext: The ciphertext to decrypt.
545
546        :param padding: An instance of
547            :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`.
548
549        :return bytes: Decrypted data.
550
551    .. method:: public_key()
552
553        :return: :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`
554
555        An RSA public key object corresponding to the values of the private key.
556
557    .. attribute:: key_size
558
559        :type: int
560
561        The bit length of the modulus.
562
563    .. method:: sign(data, padding, algorithm)
564
565        .. versionadded:: 1.4
566        .. versionchanged:: 1.6
567            :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed`
568            can now be used as an ``algorithm``.
569
570        Sign one block of data which can be verified later by others using the
571        public key.
572
573        :param bytes data: The message string to sign.
574
575        :param padding: An instance of
576            :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`.
577
578        :param algorithm: An instance of
579            :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` or
580            :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed`
581            if the ``data`` you want to sign has already been hashed.
582
583        :return bytes: Signature.
584
585
586.. class:: RSAPrivateKeyWithSerialization
587
588    .. versionadded:: 0.8
589
590    This interface contains additional methods relating to serialization.
591    Any object with this interface also has all the methods from
592    :class:`RSAPrivateKey`.
593
594    .. method:: private_numbers()
595
596        Create a
597        :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers`
598        object.
599
600        :returns: An
601            :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers`
602            instance.
603
604    .. method:: private_bytes(encoding, format, encryption_algorithm)
605
606        Allows serialization of the key to bytes. Encoding (
607        :attr:`~cryptography.hazmat.primitives.serialization.Encoding.PEM` or
608        :attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER`),
609        format (
610        :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.TraditionalOpenSSL`
611        or
612        :attr:`~cryptography.hazmat.primitives.serialization.PrivateFormat.PKCS8`)
613        and encryption algorithm (such as
614        :class:`~cryptography.hazmat.primitives.serialization.BestAvailableEncryption`
615        or :class:`~cryptography.hazmat.primitives.serialization.NoEncryption`)
616        are chosen to define the exact serialization.
617
618        :param encoding: A value from the
619            :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum.
620
621        :param format: A value from the
622            :class:`~cryptography.hazmat.primitives.serialization.PrivateFormat`
623            enum.
624
625        :param encryption_algorithm: An instance of an object conforming to the
626            :class:`~cryptography.hazmat.primitives.serialization.KeySerializationEncryption`
627            interface.
628
629        :return bytes: Serialized key.
630
631
632.. class:: RSAPublicKey
633
634    .. versionadded:: 0.2
635
636    An `RSA`_ public key.
637
638    .. method:: encrypt(plaintext, padding)
639
640        .. versionadded:: 0.4
641
642        Encrypt data with the public key.
643
644        :param bytes plaintext: The plaintext to encrypt.
645
646        :param padding: An instance of
647            :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`.
648
649        :return bytes: Encrypted data.
650
651    .. attribute:: key_size
652
653        :type: int
654
655        The bit length of the modulus.
656
657    .. method:: public_numbers()
658
659        Create a
660        :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers`
661        object.
662
663        :returns: An
664            :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicNumbers`
665            instance.
666
667    .. method:: public_bytes(encoding, format)
668
669        Allows serialization of the key to bytes. Encoding (
670        :attr:`~cryptography.hazmat.primitives.serialization.Encoding.PEM` or
671        :attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER`) and
672        format (
673        :attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo`
674        or
675        :attr:`~cryptography.hazmat.primitives.serialization.PublicFormat.PKCS1`)
676        are chosen to define the exact serialization.
677
678        :param encoding: A value from the
679            :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum.
680
681        :param format: A value from the
682            :class:`~cryptography.hazmat.primitives.serialization.PublicFormat` enum.
683
684        :return bytes: Serialized key.
685
686    .. method:: verify(signature, data, padding, algorithm)
687
688        .. versionadded:: 1.4
689        .. versionchanged:: 1.6
690            :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed`
691            can now be used as an ``algorithm``.
692
693        Verify one block of data was signed by the private key
694        associated with this public key.
695
696        :param bytes signature: The signature to verify.
697
698        :param bytes data: The message string that was signed.
699
700        :param padding: An instance of
701            :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`.
702
703        :param algorithm: An instance of
704            :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` or
705            :class:`~cryptography.hazmat.primitives.asymmetric.utils.Prehashed`
706            if the ``data`` you want to verify has already been hashed.
707
708        :raises cryptography.exceptions.InvalidSignature: If the signature does
709            not validate.
710
711
712.. class:: RSAPublicKeyWithSerialization
713
714    .. versionadded:: 0.8
715
716    Alias for :class:`RSAPublicKey`.
717
718
719.. _`RSA`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)
720.. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
721.. _`specific mathematical properties`: https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Key_generation
722.. _`use 65537`: https://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html
723.. _`at least 2048`: https://www.cosic.esat.kuleuven.be/ecrypt/ecrypt2/documents/D.SPA.20.pdf
724.. _`OpenPGP`: https://en.wikipedia.org/wiki/Pretty_Good_Privacy
725.. _`Chinese Remainder Theorem`: https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Using_the_Chinese_remainder_algorithm
726.. _`security proof`: https://eprint.iacr.org/2001/062.pdf
727.. _`recommended padding algorithm`: https://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html
728.. _`proven secure`: https://cseweb.ucsd.edu/~mihir/papers/oae.pdf
729