2
$\begingroup$

As I understand pkcs12 defines a container structure that can hold both a certificate and one or more private keys.

openssl pkcs12 -export -inkey test-key.pem -out test.p12 -name 'Test name' -in test.crt 
Enter pass phrase for test-key.pem: KEYPW
Enter Export Password: EXPPW
Verifying - Enter Export Password: EXPPW

Read the p12 file:

openssl pkcs12  -info -in test.p12 
Enter Import Password: EXPPW
<outputs certificate, followed by>
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Bag Attributes
    friendlyName: Test name
    localKeyID: 92 C7 F8 7A 23 F4 03 21 0A 3B D6 CE 29 C6 45 C8 1E E0 D2 DD 
Key Attributes: <No Attributes>
Enter PEM pass phrase: KEYPW
Verifying - Enter PEM pass phrase: KEYPW
-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----

For the PEM pass phrase I use the one when the private key was created. But why does the output show encrypted private key instead of private key? That's why I entered the pass phrase isn't it?

What makes it even more confusing: passing option -nodes to the openssl command doesn't ask the pass phrase anymore (as expected) but still shows the private key, this time not encrypted anymore. I would expect the opposite: without pass phrase show the encrypted private key, with pass phrase show the unencrypted private key. After all, I can only use the private key when it is not encrypted.

EDIT: hopefully it's easier if I ask smaller questions. Given the created test.p12 as shown above:

  1. Is it correct that EXPPW is the p12 container password and KEYPW is the pass phrase to protect the private key?
  2. Is it possible to get the unencrypted private key with only EXPPW? In other words, is KEYPW not used inside the p12 container?
  3. If the private key is stored encrypted inside the p12 using EXPPW, why does openssl pkcs12 -info -in test.p12 not accept a new pass phrase for outputting the new encrypted private key? If you don't use the original KEYPW it fails with Error outputting keys and certificates.
  4. Is it possible to protect the whole p12 container with password X and the private key with password Y? So that if you know X, you can still get the public certificate yet you can't get the private key?
$\endgroup$
  • $\begingroup$ If you are asking why the OpenSSL developers decided to put those values in the PEM header, you should probably ask in an OpenSSL forum, and not here, because it is an implementation specific question, and not a cryptographic one. $\endgroup$ – Henrick Hellström Mar 9 at 13:19
  • $\begingroup$ I am trying to understand how pkcs12 really works. Is it using 2 different passwords for 2 different things? If not, is it using 1 password for 2 different things? Why can I get the private key without pass phrase? I don't get what you mean by "those values in the PEM header". $\endgroup$ – rob Mar 9 at 15:06
  • $\begingroup$ No Pkcs#12, as such and if the implementation conforms with the specification, uses one password. The PEM wrapper, however, is something specific to the OpenSSL implementation, and has nothing to do with Pkcs#12. I can't say what OpenSSL does here and why. $\endgroup$ – Henrick Hellström Mar 9 at 16:28
  • 1
    $\begingroup$ It seems to me that it is about the export of the private key, which is what you do for when you are, for instance, listing the certificates and keys. So if you supply -nodes after already being able to access it, is that you get the plain key. While if you use -3des, the default, then it is encrypted before it is being shown. $\endgroup$ – Maarten Bodewes Mar 9 at 18:58
  • 1
    $\begingroup$ @MaartenBodewes+ my goal is to understand the pkcs12 structure. I use the openssl tool to get a better understanding about the whole thing. In addition, I will have to program in C by calling the openssl API so I'm not primary interested int the command line tool. Also I'm still very confused. Therefore I'll edit the original question and split my question into sub-questions. $\endgroup$ – rob Mar 10 at 13:35
0
$\begingroup$

Now that the Qs have been clarified (and yes this isn't really about cryptography, and would be more appropriate on security.SX = application of crypto in systems or superuser = use of programs including security programs like OpenSSL or maybe even stackoverflow)

... Given the example ... 1. Is it correct that EXPPW is the p12 container password and KEYPW is the pass phrase to protect the private key?

No. KEYPW was the passphrase on the PEM-format input file. If the input privatekey file is unencrypted (which OpenSSL supports, although it in many situations it is insecure and thus a Bad Idea) the input password is not even prompted for. It is not used in the P12; only EXPPW is used for the P12.

  1. Is it possible to get the unencrypted private key with only EXPPW? In other words, is KEYPW not used inside the p12 container?

Yes. That's exactly what your openssl pkcs12 -nodes (with EXPPW) does. (Again OpenSSL supports it, but the caveat above about using an unencrypted privatekey file applies.)

  1. If the private key is stored encrypted inside the p12 using EXPPW, why does openssl pkcs12 -info -in test.p12 not accept a new pass phrase for outputting the new encrypted private key? If you don't use the original KEYPW it fails with Error outputting keys and certificates

Try again. It should work (to use a different password on the output of the 'parse') and does for me. Note the new password must be at least 4 characters, a limit that OpenSSL does not enforce in other places, although even 4 is not nearly enough for actual security. (That area -- length and other characteristics of a good password -- is ontopic for crypto.SX and has been discussed numerous times at length.)

  1. Is it possible to protect the whole p12 container with password X and the private key with password Y? So that if you know X, you can still get the public certificate yet you can't get the private key?

Yes, or nearly. There are actually three operations normally done:

  1. the whole P12 is MACed using a password,

  2. the 'shrouded keybag' is encrypted using a password, and usually a strong or at least strong-ish algorithm like 3DES

  3. the 'cert bag' is (separately) encrypted using a password, and usually a deliberately weak algorithm namely RC2-40

(The latter two are shown by the -info option on the parse subcommand, although you omitted part from your post.)

OpenSSL commandline does not support using different passwords for 2 and 3, but it does support changing the algorithm(s) and in particular it supports making the certbag unencrypted which allows access to it without the password, using -certpbe NONE. This is a crossdupe of https://superuser.com/questions/1507936/openssl-encrypts-public-key-after-conversion-to-pfx . Commandline does support the -twopass option to make the MAC password for 1 different from 3 (or 2 and 3), or you can simply ignore the password for 1 on reading using -nomacver.

Caveat: software other than OpenSSL may not handle PKCS12 files with other than the usual algorithm settings and a single password.

my goal is to understand the pkcs12 structure.

You might want to look directly at the file structure with asn1parse, rather than the interpretation given by the pkcs12 command. See an example at https://stackoverflow.com/questions/51242721/openssl-debugging-how-to-dump-intermediate-asn-1-inside-openssl

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you for making this clear! As of question 3, the password I used for testing was too short, whereas the original PEM pass phrase was much longer. Using a longer password indeed works. If this post better belongs on security.stackexchange then maybe someone can move it over? $\endgroup$ – rob Mar 11 at 10:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.