@@ -491,12 +491,20 @@ file suffix.
491491
492492 .. versionadded :: 3.0
493493
494+ .. note ::
495+ With OpenSSL 3.0.0+ the defaults for encryption when serializing PKCS12
496+ have changed and some versions of Windows and macOS will not be able to
497+ read the new format. Maximum compatibility can be achieved by using
498+ ``SHA1 `` for MAC algorithm and
499+ :attr: `~cryptography.hazmat.primitives.serialization.pkcs12.PBES.PBESv1SHA1And3KeyTripleDESCBC `
500+ for encryption algorithm as seen in the example below. However, users
501+ should avoid this unless required for compatibility.
502+
494503 .. warning ::
495504
496- PKCS12 encryption is not secure and should not be used as a security
497- mechanism. Wrap a PKCS12 blob in a more secure envelope if you need
498- to store or send it safely. Encryption is provided for compatibility
499- reasons only.
505+ PKCS12 encryption is typically not secure and should not be used as a
506+ security mechanism. Wrap a PKCS12 blob in a more secure envelope if you
507+ need to store or send it safely.
500508
501509 Serialize a PKCS12 blob.
502510
@@ -535,11 +543,41 @@ file suffix.
535543 :param encryption_algorithm: The encryption algorithm that should be used
536544 for the key and certificate. An instance of an object conforming to the
537545 :class: `~cryptography.hazmat.primitives.serialization.KeySerializationEncryption `
538- interface. PKCS12 encryption is **very weak ** and should not be used
539- as a security boundary.
546+ interface. PKCS12 encryption is typically **very weak ** and should not
547+ be used as a security boundary.
540548
541549 :return bytes: Serialized PKCS12.
542550
551+ .. doctest ::
552+
553+ >>> from cryptography import x509
554+ >>> from cryptography.hazmat.primitives.serialization import BestAvailableEncryption, load_pem_private_key, pkcs12
555+ >>> cert = x509.load_pem_x509_certificate(ca_cert)
556+ >>> key = load_pem_private_key(ca_key, None )
557+ >>> p12 = pkcs12.serialize_key_and_certificates(
558+ ... b " friendlyname" , key, cert, None , BestAvailableEncryption(b " password" )
559+ ... )
560+
561+ This example uses an ``encryption_builder() `` to create a PKCS12 with more
562+ compatible, but substantially worse, encryption.
563+
564+ .. doctest ::
565+
566+ >>> from cryptography import x509
567+ >>> from cryptography.hazmat.primitives import hashes
568+ >>> from cryptography.hazmat.primitives.serialization import PrivateFormat, load_pem_private_key, pkcs12
569+ >>> encryption = (
570+ ... PrivateFormat.PKCS12 .encryption_builder().
571+ ... kdf_rounds(50000 ).
572+ ... key_cert_algorithm(pkcs12.PBES .PBESv1SHA1And3KeyTripleDESCBC).
573+ ... mac_algorithm(hashes.SHA1()).build(b " my password" )
574+ ... )
575+ >>> cert = x509.load_pem_x509_certificate(ca_cert)
576+ >>> key = load_pem_private_key(ca_key, None )
577+ >>> p12 = pkcs12.serialize_key_and_certificates(
578+ ... b " friendlyname" , key, None , None , encryption
579+ ... )
580+
543581.. class :: PKCS12Certificate
544582
545583 .. versionadded :: 36.0
@@ -579,6 +617,24 @@ file suffix.
579617 A list of :class: `~cryptography.hazmat.primitives.serialization.pkcs12.PKCS12Certificate `
580618 instances.
581619
620+ .. class :: PBES
621+
622+ .. versionadded :: 38.0.0
623+
624+ An enumeration of password-based encryption schemes used in PKCS12. These
625+ values are used with
626+ :class: `~cryptography.hazmat.primitives.serialization.KeySerializationEncryptionBuilder `.
627+
628+ .. attribute :: PBESv1SHA1And3KeyTripleDESCBC
629+
630+ PBESv1 using SHA1 as the KDF PRF and 3-key triple DES as the cipher.
631+
632+ .. attribute :: PBESv2SHA256AndAES256CBC
633+
634+ PBESv2 using SHA256 as the KDF PRF and AES256 as the cipher. This is
635+ only supported on OpenSSL 3.0.0 or newer.
636+
637+
582638PKCS7
583639~~~~~
584640
@@ -841,16 +897,41 @@ Serialization Formats
841897 ...
842898 -----END OPENSSH PRIVATE KEY-----
843899
900+ .. attribute :: PKCS12
901+
902+ .. versionadded :: 38.0.0
903+
904+ The PKCS#12 format is a binary format used to store private keys and
905+ certificates. This attribute is used in conjunction with
906+ ``encryption_builder() `` to allow control of the encryption algorithm
907+ and parameters.
908+
909+ .. doctest ::
910+
911+ >>> from cryptography.hazmat.primitives import hashes
912+ >>> from cryptography.hazmat.primitives.serialization import PrivateFormat, pkcs12
913+ >>> encryption = (
914+ ... PrivateFormat.PKCS12 .encryption_builder().
915+ ... kdf_rounds(50000 ).
916+ ... key_cert_algorithm(pkcs12.PBES .PBESv2SHA256AndAES256CBC).
917+ ... mac_algorithm(hashes.SHA256()).build(b " my password" )
918+ ... )
919+ >>> pkcs12.serialize_key_and_certificates(
920+ ... b " friendlyname" , key, None , None , encryption
921+ ... )
922+ b'...'
923+
844924 .. method :: encryption_builder()
845925
846926 .. versionadded :: 38.0.0
847927
848928 Returns a builder for configuring how values are encrypted with this
849- format.
929+ format. You must call this method on an element of the enumeration.
930+ For example, ``PrivateFormat.OpenSSH.encryption_builder() ``.
850931
851932 For most use cases, :class: `BestAvailableEncryption ` is preferred.
852933
853- :returns KeySerializationEncryptionBuilder : A new builder.
934+ :returns: A new instance of :class: ` KeySerializationEncryptionBuilder `
854935
855936 .. doctest ::
856937
@@ -1022,7 +1103,8 @@ Serialization Encryption Types
10221103
10231104 Encrypt using the best available encryption for a given key.
10241105 This is a curated encryption choice and the algorithm may change over
1025- time.
1106+ time. The encryption algorithm may vary based on which version of OpenSSL
1107+ the library is compiled against.
10261108
10271109 :param bytes password: The password to use for encryption.
10281110
@@ -1033,25 +1115,43 @@ Serialization Encryption Types
10331115
10341116.. class :: KeySerializationEncryptionBuilder
10351117
1036- A builder that can be used to configure how key data is encrypted. To
1037- create one, call :meth: `PrivateFormat.encryption_builder `.
1118+ .. versionadded :: 38.0.0
1119+
1120+ A builder that can be used to configure how data is encrypted. To
1121+ create one, call :meth: `PrivateFormat.encryption_builder `. Different
1122+ serialization types will support different options on this builder.
10381123
10391124 .. method :: kdf_rounds(rounds)
10401125
10411126 Set the number of rounds the Key Derivation Function should use. The
10421127 meaning of the number of rounds varies on the KDF being used.
10431128
10441129 :param int rounds: Number of rounds.
1045- :returns KeySerializationEncryptionBuilder: A new builder.
1130+
1131+ .. method :: key_cert_algorithm(algorithm)
1132+
1133+ Set the encryption algorithm to use when encrypting the key and
1134+ certificate in a PKCS12 structure.
1135+
1136+ :param algorithm: A value from the :class: `~cryptography.hazmat.primitives.serialization.pkcs12.PBES `
1137+ enumeration.
1138+
1139+ .. method :: mac_algorithm(algorithm)
1140+
1141+ Set the MAC algorithm to use for a PKCS12 structure.
1142+
1143+ :param algorithm: An instance of a
1144+ :class: `~cryptography.hazmat.primitives.hashes.HashAlgorithm `
10461145
10471146 .. method :: build(password)
10481147
10491148 Turns the builder into an instance of
10501149 :class: `KeySerializationEncryption ` with a given password.
10511150
10521151 :param bytes password: The password.
1053- :returns KeySerializationEncryption: A key key serialization
1054- encryption that can be passed to ``private_bytes `` methods.
1152+ :returns: A :class: `KeySerializationEncryption ` encryption object
1153+ that can be passed to methods like ``private_bytes `` or
1154+ :func: `~cryptography.hazmat.primitives.serialization.pkcs12.serialize_key_and_certificates `.
10551155
10561156.. _`a bug in Firefox` : https://bugzilla.mozilla.org/show_bug.cgi?id=773111
10571157.. _`PKCS3` : https://www.teletrust.de/fileadmin/files/oid/oid_pkcs-3v1-4.pdf
0 commit comments