How is a private key encrypted in a pem certificate? How is a private key encrypted in a pem certificate? curl curl

How is a private key encrypted in a pem certificate?


Private keys can have a couple of different forms of being written down, but the most common form is PKCS#8, defined in RFC 5208.

The RFC defines two forms of structure.

PrivateKeyInfo ::= SEQUENCE {  version                   Version,  privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,  privateKey                PrivateKey,  attributes           [0]  IMPLICIT Attributes OPTIONAL }

"The version number for this structure, in case it evolves", "how to identify what parser to use to read privateKey", "some stuff, hope you can read it", "some data about the stuff, maybe".

When PEM encoded a PrivateKeyInfo gets the tag "PRIVATE KEY", as in "BEGIN PRIVATE KEY". You don't have one of these.

The other form is

EncryptedPrivateKeyInfo ::= SEQUENCE {  encryptionAlgorithm  EncryptionAlgorithmIdentifier,  encryptedData        EncryptedData }

"How I encrypted stuff", "the encrypted stuff".

EncryptedPrivateKeyInfo comes with the PEM tag "ENCRYPTED PRIVATE KEY", which is what you have.

Looking into one of those:

$ openssl asn1parse -i -dump < rsa.enc.p8    0:d=0  hl=4 l= 710 cons: SEQUENCE    4:d=1  hl=2 l=  64 cons:  SEQUENCE    6:d=2  hl=2 l=   9 prim:   OBJECT            :PBES2   17:d=2  hl=2 l=  51 cons:   SEQUENCE   19:d=3  hl=2 l=  27 cons:    SEQUENCE   21:d=4  hl=2 l=   9 prim:     OBJECT            :PBKDF2   32:d=4  hl=2 l=  14 cons:     SEQUENCE   34:d=5  hl=2 l=   8 prim:      OCTET STRING      0000 - e9 37 68 99 cb 9c 4f 10-                          .7h...O.   44:d=5  hl=2 l=   2 prim:      INTEGER           :0800   48:d=3  hl=2 l=  20 cons:    SEQUENCE   50:d=4  hl=2 l=   8 prim:     OBJECT            :des-ede3-cbc   60:d=4  hl=2 l=   8 prim:     OCTET STRING      0000 - 16 ad ce 41 47 e8 ba 85-                          ...AG...   70:d=1  hl=4 l= 640 prim:  OCTET STRING     <data_omitted />

The data was encrypted under Password-Based Encryption Scheme 2 (PBES2). The input password/passphrase is transformed into key material by Password-Based Key Derivation Function 2 (PBKDF2) with the salt (randomly chosen at encryption time, but must be the same to decrypt) e9 37 68 99 cb 9c 4f 10 and using an iteration count of 2048 (0x800). The key was used for TripleDES encryption in CBC mode with an IV (randomly chosen at encryption time, but must be the same to decrypt) of 16 ad ce 41 47 e8 ba 85. The encrypted content is 640 bytes, and will then be parsed as a PrivateKeyInfo structure.

Aside from PKCS#8 the only real other choice for transmitting private keys is PKCS#12/PFX, but that data structure doesn't have a standard PEM representation. The newest version of PKCS#12 allows for encrypting the data to a certificate, in the style of EnvelopedCMS/PKCS#7.

So, for some succinct answers:

  • The ENCRYPTED PRIVATE KEY form is encrypted.
    • It's 99.999% likely that it's encrypted with a passphrase.
    • But someone may have taught OpenSSL about a PBES2 KDF using something other than passphrases :).
  • The PRIVATE KEY form is not encrypted.
    • The RSA PRIVATE KEY form is also not encrypted, but that's a PKCS#1 RSAPrivateKey, not a PKCS#8 PrivateKeyInfo.
  • If curl doesn't prompt you for a passphrase then it doesn't support encrypted private keys.
  • While it's not impossible that an encrypted private key could exist sans passphrase, it's definitely not common, and definitely not in a PEM encoded payload.


If you are using passphrase, of course your key is encrypted !

A passphrase is a word or phrase that protects private key files. It prevents unauthorized users from encrypting them. Usually it's just the secret encryption/decryption key used for Ciphers.