PKCS#8¶
PKCS#8 is a standard for encoding asymmetric private keys, such as RSA or ECC, so that they can be stored or exchanged. The private key can either be encrypted with a passphrase or left in the clear.
Example of how to encrypt an ECC private key (even though
normally you would use the export_key method of the key itself):
from Crypto.PublicKey import ECC
from Crypto.IO import PKCS8
key = ECC.generate(curve='p256')
pkey = key.export_key(format='DER')
passphrase = b'secret santa'
encrypted_key = PKCS8.wrap(
pkey,
"1.2.840.10045.2.1", # unrestricted ECC
passphrase=passphrase,
protection='PBKDF2WithHMAC-SHA256AndAES256-CBC'
)
Encryption parameters¶
When creating an encrypted PKCS#8 container, the two parameters
protection and prot_params drive the encryption algorithm:
protection(optional, the default is'PBKDF2WithHMAC-SHA256AndAES256-CBC'), a string that defines how the encryption key is derived from the passphrase, and which cipher to use. The string must follow one of the two patterns:'PBKDF2WithHMAC-'+ hash +'And'+ cipher'scryptAnd'+ cipher
where hash is the name of the cryptographic hash (recommended:
'SHA256') and cipher is the name of the cipher mode to use (recommended:'AES256-CBC').Other values for hash are
'SHA1','SHA224','SHA256','SHA384','SHA512-224','SHA512-256','SHA3-224','SHA3-256','SHA3-384','SHA3-512'.Other values for cipher are
'AES128-GCM','AES192-GCM','AES256-GCM','AES128-CBC','AES192-CBC'or'DES-EDE3-CBC'.prot_params(optional), a dictionary to override the parameters of the key derivation function. The defaults meet the OWASP recommendations for scrypt and for PBKDF2 with SHA-256 or SHA-512 (but not SHA-1, which should not be used): there is no need to change them, except to make the key cheaper to decrypt (for instance, on a slow device).Key
Description
iteration_count
The KDF algorithm is repeated several times to slow down brute force attacks on passwords (called N or CPU/memory cost in scrypt).
The default value is 600 000 for PBKDF2 (whatever the hash), and 131 072 for scrypt.
salt_size
Salt is used to thwart dictionary and rainbow attacks on passwords. The default value is 8 bytes.
block_size
(scrypt only) Memory-cost (r). The default value is 8.
parallelization
(scrypt only) CPU-cost (p). The default value is 1.
With scrypt, the parallelization parameter (p) defines independent
computations, which can run on several CPU cores: use the threads parameter
of wrap() and unwrap(), of import_key() for RSA, DSA and ECC keys,
and of export_key() for RSA and ECC keys.
With threads=0, as many threads as the CPU cores available are used.
Each thread needs its own block of memory (128 · r · N bytes), at the same time.
The result does not depend on the number of threads.
Limits for decryption¶
To protect against malicious keys, unwrap() rejects keys whose key derivation
is too expensive (parameters max_iteration_count and max_memory).
See Limits when decrypting private keys for the default limits and how to change them.
Legacy algorithms¶
The following protection mechanisms are only supported for importing keys.
They are much weaker than the ones listed above, and they are provided
for backward compatibility only:
pbeWithMD5AndRC2-CBCpbeWithMD5AndDES-CBCpbeWithSHA1AndRC2-CBCpbeWithSHA1AndDES-CBC
- class Crypto.IO.PKCS8.UnwrappedKey(iterable=(), /)¶
The result of
unwrap().It is a tuple
(oid, private_key, params), so that it can be indexed or unpacked into three variables, and it has the attributes listed below.- property params: bytes | None¶
The
parametersof theAlgorithmIdentifier(bytes, DER encoded), orNoneif they are absent orNULL.
-
public_key:
Optional[bytes]¶ The
publicKeyfield of aOneAsymmetricKeyversion 2 (RFC 5958), as bytes (the content of the BIT STRING), orNoneif it is absent. It is returned also if the version of the structure is 1, where the field is not allowed: it is up to the caller to reject it or to check that it matches the private key.
- Crypto.IO.PKCS8.unwrap(p8_private_key, passphrase=None, max_iteration_count=None, *, threads=1, max_memory=None)¶
Unwrap a private key from a PKCS#8 blob (clear or encrypted).
- Parameters:
p8_private_key (bytes) – The private key wrapped into a PKCS#8 container, DER encoded.
- Keyword Arguments:
passphrase (byte string or string) – The passphrase to use to decrypt the blob (if it is encrypted).
max_iteration_count (integer) – The maximum value allowed for the PBKDF1/PBKDF2 iteration count, or for the scrypt cost N·r·p/8 (that is, N for the usual r=8 and p=1). An attacker could craft a malicious key blob that requires an extremely high number of iterations, tying up the CPU for hours. The default value is None: a limit for each KDF, which keeps the key derivation to about one minute at most (see the limits for decryption). Set it to
0to disable the check.threads (integer) – The maximum number of threads used to derive the unwrapping key with scrypt (default: 1, no extra threads; 0 for all CPU cores). Only a blob protected with scrypt and a parallelization parameter larger than 1 can use them. See
Crypto.Protocol.KDF.scrypt().max_memory (integer) – The maximum memory (in bytes) for the key derivation, as a limit on the total of all threads together (not on each thread). Only scrypt uses a significant amount: 128 · (N + 2) · r bytes for each thread, plus 256 · r · p bytes for all the flows together. If the requested threads do not fit, fewer are used (down to one); if a single thread does not fit,
Crypto.KdfMemoryLimitErroris raised. The default value is None (a limit of 256 MiB). Set it to0to disable the check.
- Returns:
a tuple containing
the algorithm identifier of the wrapped key (OID, dotted string)
the private key (bytes, DER encoded)
the associated parameters (bytes, DER encoded) or
None(also if they areNULL)
with the same items as attributes, plus the attribute
public_key.- Return type:
- Raises:
PassphraseRequiredError – (a
ValueError) if the blob is encrypted and no passphrase has been providedIncorrectPassphraseError – (a
ValueError) if the blob cannot be decrypted with the passphrase (most likely, the passphrase is incorrect)KdfIterationLimitError – (a
ValueError) if the iteration count is abovemax_iteration_countKdfMemoryLimitError – (a
ValueError) if the key derivation needs more memory thanmax_memoryValueError – if decoding fails for any other reason
- Crypto.IO.PKCS8.wrap(private_key, key_oid, passphrase=None, protection=None, prot_params=None, key_params=<Crypto.Util.asn1.DerNull object>, randfunc=None, *, threads=1, public_key=None)¶
Wrap a private key into a PKCS#8 blob (clear or encrypted).
- Parameters:
private_key (bytes) – The private key encoded in binary form. The actual encoding is algorithm specific. In most cases, it is DER.
key_oid (string) – The object identifier (OID) of the private key to wrap. It is a dotted string, like
'1.2.840.113549.1.1.1'(for RSA keys) or'1.2.840.10045.2.1'(for ECC keys).
- Keyword Arguments:
passphrase (bytes or string) – The secret passphrase from which the wrapping key is derived. Set it only if encryption is required.
protection (string) – The identifier of the algorithm to use for securely wrapping the key. Refer to the encryption parameters . The default value is
'PBKDF2WithHMAC-SHA256AndAES256-CBC'.prot_params (dictionary) – Parameters for the key derivation function (KDF). Refer to the encryption parameters .
key_params (DER object or None) – The
parametersfield to use in theAlgorithmIdentifierSEQUENCE. IfNone, noparametersfield will be added. By default, the ASN.1 typeNULLis used.randfunc (callable) – Random number generation function; it should accept a single integer N and return a string of random data, N bytes long. If not specified, a new RNG will be instantiated from
Crypto.Random.threads (integer) – The maximum number of threads used to derive the wrapping key with scrypt (default: 1, no extra threads; 0 for all CPU cores). Only scrypt with a
parallelizationlarger than 1 can use them. SeeCrypto.Protocol.KDF.scrypt().public_key (bytes) – The public key, to store in the field
publicKey. The actual encoding is algorithm specific. If set, the result is aOneAsymmetricKeyversion 2 (RFC 5958), otherwise it is aPrivateKeyInfo(version 1, the default).
- Returns:
The PKCS#8-wrapped private key (possibly encrypted).
- Return type: