OpenSSL PKCS#12 FAQ v1.84

Contents.

  1. Introduction and latest changes.
  2. Basics.
  3. Common problems.
  4. Technical queries.

Introduction and latest changes.

There are several questions that crop up frequently relating to PKCS#12 support in OpenSSL. After replying to the same things several times I decided to write an FAQ to deal with them.

Note: from this version onwards I am not including details of the obsolete PKCS#12 patch, the external PKCS#12 program or ca-fix. The FAQ was getting confusing when I needed to include several versions of the same commands for older versions of OpenSSL and SSLeay. Therefore all commands assume you are using OpenSSL 0.9.5a or later. It is also assumed that you are using MSIE 5 or later, there are some security issues with MSIE4 mentioned in the older FAQ.

You may have noticed that this version looks different. My thanks to Barry Rountree for reformatting it.


Basics.

Q. How can I get your PKCS#12 program?
A. My PKCS#12 program is now part of OpenSSL. If you compile the latest version of OpenSSL the pkcs12 program will be available as part of the openssl command line utility.
Q. What is PKCS#12?
A. PKCS#12 is a standard for storing private keys and certificates securely (well sort of). It is used in (among other things) Netscape and Microsoft Internet Explorer with their import and export options.
Q. Is your PKCS#12 implementation compatible with Netscape and MSIE versions?
A. Yes it is. You can readily export PKCS#12 files and have my patch pull them apart or generate PKCS#12 files that MSIE and NS will import - but see the Usage section below.
Q. What about PFX is it the same as PKCS#12 or what?
A. PFX in its correct form is an almost unused predecessor to PKCS#12. Occasionally people incorrectly use the term "PFX" when they mean "PKCS#12". More details in the older FAQ.
Q. What is the copyright status of your code?
A. Since it is part of OpenSSL it is released under the OpenSSL licence.
Q. Why should I use PKCS#12?
A. Other than the obvious reason that you want PKCS#12 :-) It's probably the easiest way to generate your own certificates for MSIE and NS. You don't need a separate server and you can add them simply by importing a file. It is also the only way to access the private keys of other certificates (e.g. issued by a standard CA).

Common problems.

Q. What do all those horrible options do?
A. I get the occasional comment that the various options are rather cryptic. Here is a description of them and their typical use.
Q. I followed the instructions for generating client certificates but the certificates seem to be invalid: when I try to use them for SSL client authentication I get a box saying I have no client certificates (Communicator) or an empty listbox asking me to select a certificate (MSIE).
A. This is actually nothing to do with my PKCS#12 program but it gets asked so much I'll include the answer here. With all versions of MSIE and Netscape 4.05 or later you can only use a certificate for SSL client authentication if the CA is sent in the acceptable CA list by the server: so if it doesn't work your server is misconfigured. How you include the CA in the list depends on the server in question: with Apache SSL for example you include your client CA in the directory pointed to by SSLCACertificatePath and do a c_rehash <dir> or append it to the file pointed to by SSLCACertificateFile. You can use the s_client program to check if your CA appears in the list.

Netscape Communicator Specific Issues.

Q. I can't seem to import a PKCS#12 file into Netscape. Why?
A. One common reason if that you haven't set a friendly name with the -name option. If you don't set this it may complain. Alternatively if you are using an ancient version of Netscape (4.03 or earlier) you should read the PFX section of my older FAQ.
Q. I'm using Netscape 3.0x can I still use your program or PFX or some equivalent?
A. No: they don't support PKCS#12 or PFX nor is it possible to directly access the key and certificate database because its format is undocumented.
Q. Are there any issues relating to Netscape private key security?
A.  If you delete a certificate it still retains the private key in the database: from where it can be retrieved by anyone with the appropriate knowledge (e.g. me) and the Communicator password. The easiest way to delete the private key is by deleting the key3.db and cert7.db files in the Communicator directory. This deletes all private keys, be very very sure this is what you want. There are circumstances where you will also need to delete or rename the Netscape 3.0 database files called key.db and cert5.db. The reason for this is that if Communicator doesn't see the key3.db and cert7.db files but does see the older database files it reads in and converts the older files (when you next give the password).
Q. Netscape complains that my certificate is not certified for email, why?
A. This is usually because you've changed the value of nsCertType (see openssl.cnf). For email and normal client verification you need the option: nsCertType=email,client. Alternatively you can comment out the nsCertType line completely to get S/MIME and SSL client use (which is probably what you want).
Q. I want to use the certificate for object signing with Netscape: how do I do this?
A. You need to set nsCertType to objsign,email,client  (or just objsign for just object signing and nothing else) and include the correct value in the CA certificate: nsCertType objCA,sslCA,emailCA or just objCA.

Otherwise things proceed as per the instructions for the signing tools. It appears that (unlike email) Netscape does not install an object signing CA certificate as untrusted if it does not recognize it. This means that if you want your object signing CA to be recognized its certificate needs to be already loaded and trusted in the user's database.

Q. When I send mail to someone they say that although my CA is added to the list of signers but they cannot select it in order to trust it!
A. This problem has recently been brought to my attention. In this case it was apparently due to ampersand characters (&) in the CA fields. I say apparently because, although I can reproduce the problem by reading the signed mail in question, I have been unable to reproduce it by generating CAs and certificates with & characters in them. I'll give more info if I can determine the precise cause of this.
Q. The recreated file is quite a bit smaller than the original NS one, why?
A. For some reason the encoding used by NS is not very efficient. The encoding used by my patch is somewhat better (actually its the definite length encoding in OpenSSL).

Q. I'm having real problems getting a certificate into Netscape. Help!

A. OK here is a step by step guide on how to do things.
  1. Create a CA. E.g. use CA.pl -newca.
  2. Extend the CA expiry date with e.g.:
    openssl x509 -in demoCA/cacert.pem -days 1024 -out cacert.pem -signkey demoCA/private/cakey.pem
  3. Then copy the file cacert.pem over the older demo/cacert.pem
  4. Check the nsCertType line in openssl.cnf  reads email, sslclient or just comment it out for S/MIME and SSL Client use (this is the default). For object signing only use objsign for all three use email, sslclient, objsign.
  5. Create a new certificate request with CA.pl -newreq
  6. Sign the request with CA.pl -signreq
  7. Create a PKCS#12 file with:
    openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -certfile demoCA/cacert.pem -name "MY CERTIFICATE" -out mycert.p12
  8. mycert.p12 file into Netscape: Security->Yours->Import.
  9. You should now have the CA certificate in "signers". Set it to trust the CA.
  10. Try verifying the cert in Netscape.
  11. Try some test signed mail (just "save draft" then check the drafts folder).

To generate more certificates just repeat steps 5 to 10.

Q. I followed the instructions to create a client certificate but I can't seem to use the certificate for SSL client authentication: it says I have no user certificates!
A. If you can verify the certificate in Netscape then this is almost certainly due to server misconfiguration: check out the SSL client authentication question for details.

MSIE and Outlook specific issues.

Q. I'm having problem importing certificates into MSIE4.
A. MSIE4 has a number of PKCS#12 related problems and some nasty security issues. You should really upgrade to MSIE5 which is much better. Some MSIE4 issues are described in the older FAQ.
Q. Why don't I get any prompts when MSIE uses my private key?
A. This is because you have the default (low) private key security. This is more like no private key security. You need to correct this problem: see the private key security question.
Q. I can't seem to import a PKCS#12 file into MSIE. Why?
A. You noted the informative error message? There are lots of possible reasons for this. The most common reason is that you are using a user certificate with an RSA key larger than 512 bits with MSIE export version. Apply the domestic (128 bit) security patch and try again.

Alternatively if you want to use the key for signing only then you may be in luck: check out the signature key question.

Q. MSIE will import my certificate but it complains that it has expired!
A. This happens because the expiry date of the CA is before the expiry date of the certificate. If this happens you can extend the CA expiry date using the command:

openssl x509 -in cacert.pem -days 1024 -out newca.pem -signkey private/cakey.pem

and then replacing cacert.pem with newca.pem.

Q. Is there anything else to watch out for with MSIE import?
A. With MSIE5 you should either check the 'Enable strong private key protection' box or leave the 'Mark the private key as exportable' box unchecked. It is advisable to check the 'Enable strong private key protection' box so private keys cannot be used without your approval. If you leave the 'Mark the private key as exportable'  box unchecked then your private keys cannot be extracted (and hence stolen) but keep the imported PKCS#12 file safe because it is the only way to recover your private key.

Q. I'm having real problems getting a certificate into MSIE, help!
A. OK here is a step by step guide on how to do things.

1. Create a CA. E.g. use CA.pl -newca.
2. Extend the CA expiry date with e.g.:
openssl x509 -in newca.pem -days 1024 -out cacert.pem -signkey demoCA/private/cakey.pem
3. Replace the CA certificate (demoCA/cacert.pem) with the one created above.
4. If you are using MSIE5 then skip to 7, otherwise create a certificate file with:
openssl x509 -in demoCA/cacert.pem -outform DER -out cacert.der
You now need to open the cacert.der file with MSIE as MIME type application/x-x509-ca-cert. Files with extension .der seem to be already registered as this type so just transfer cacert.der to the PC and double click on it. You should then be able to open the file and set it to be trusted as a CA. Check it appears in View->Internet Options->Content->Authorities.
5.  If you are using the export version edit the default_bits section in openssl.cnf to set the key size to 512 bits.
6. Create a new certificate request with CA.sh -newreq
7. Sign the request with CA.sh -signreq
8 .Create a PKCS#12 file with:
openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -name "MY CERTIFICATE" -certfile demoCA/cacert.pem -out mycert.p12
If you are using MSIE5 then also add the maciter option to make the PKCS#12 file more secure.
9. Choose Tools->Internet Options->Content->Certificates->Import and follow the instructions in the wizard. If you haven't got the root CA added to the database it will be added automatically, but you need to confirm that you want to do this.
10.  The certificate should now be present in the list.
11. If you are using Outlook Express or Outlook try signing mail with the certificate.
12. After you are satisfied that it works OK check the private key security question and increase the security level of your newly imported private key.

If you want to generate more certificates repeat steps 7 to 10.


Q. I followed the instructions to create a client certificate but I can't seem to use the certificate for SSL client authentication: it asks me to pick a certificate from an empty listbox!
A. This is almost certainly due to server misconfiguration: check out the SSL client authentication question for details.

Q. How can I create a PKCS#12 file whose private key will be imported into a non-standard CSP such as a smart card?

A. You need to use OpenSSL 0.9.7 or later and supply the CSP name using the cspname parameter. Not all CSPs support key import so this may not work.

MSIE Authenticode issues.

My thanks to Miguel Angel Fraga  for some initial suggestions about how this might be done.

Q. How can I generate and use certificates for Authenticode?
A. This is a lot easier than it might first appear, if you handle it right. If you look at the test Authenticode certificates and authorities you see lots of horrible non standard, complex and deprecated extensions. On top of that there are things like SPC files PVK files and other nasties. Anyway enough waffle here's a step by step guide about what to do.

1. Make sure you have the latest Authenticode tools. The only version of signcode this is known to work with is 5.101.1663.1 several older versions most definitely do notwork (I had all manner of problems until I tried the latest version). The easiest place to get these is in the Microsoft Internet Client SDK. You need to use MSIE to download this properly. The latest tools are part of the common stuff that is downloaded whenever you download anything, so select a small package to download and you'll get the tools as well. They are in the bin directory.
2. Generate a CA certificate, trust it for software publishing and import an end user PKCS#12 file with the appropriate values in the certificate (if unsure how to so this just read the MSIE certificate help question). If you wish to use a key larger than 512 bits in size and you do not have the domestic security patch installed then check the signature key question. If you've already got a CA installed but you haven't set it for software publishing then you can just select View->Internet->Options->Content->Authorities and select software publishing in the listbox headed Issuer Type. Find your CA in the window and check the box next to it, assuming you haven't already done so. Increase the security level of the private key see the private key security question. The comments made there are doubly important for Authenticode private keys: it is strongly advised that you use high security and pick a good password. Never ever click on the remember password option when you access an Authenticode key.
3. Find out the commonName (CN) of your user certificate. If unsure you can use:
openssl x509 -in cert.pem -noout -subject
In case it isn't obvious the CN is the bit after CN= part. The file cert.pem if the user certificate file. If you don't have it you can always extract it from the PKCS#12 file with:
openssl pkcs12 -in myfile.p12 -clcerts -nokeys -out cert.pem
4. You should now be able to sign a something with:
signcode -cn "My Object Cert" file.dll
5. Test out the file with:
chktrust file.dll
A nice friendly dialog box should appear letting you examine who it thinks signed it and allowing all sorts of info to be displayed.

Q. Why doesn't this involve messing around messing around with SPC and PVK files?
A. Well if you really want to mess around with SPC and PVK files you can. See the next few questions.
Q. What are SPC files?
A. They are simply DER encoded PKCS#7 files containing the certificates. Well they are in the newer versions of the tools. The older versions used an invalid PKCS#7 format.
Q. How can I extract the contents of an SPC file?
A. If it was created with a newer version of the tools then try:
openssl pkcs7 -inform DER -in mycert.spc -print_certs -out certs.pem
The file certs.pem will then contain all the certificates in PEM form, you can manually cut and paste them if you want.
Q. How can I generate an SPC file?
A. The easiest way is to use the OpenSSL tools. Collect all your certificates together into one file in PEM format, you can do this easily from a PKCS#12 file with:
openssl pkcs12 -in mycert.p12 -nokeys -out certs.pem

Then use the OpenSSL program crl2pkcs7 to generate a DER encoded PKCS#7 file:
openssl crl2pkcs7 -nocrl -certfile certs.pem -outform DER -out mycert.spc
You can then use the file mycert.spc just like any other SPC file.

That's the easy way. Slightly harder is to convert each certificate to DER form with:
openssl x509 -in cert1.pem -outform DER -out cert1.der
Then use the supplied cert2spc tool:
cert2spc cert1.der cert2.der ... mycert.spc

Q. How can I use this SPC file with signcode?
A. You can use it in conjunction with the private key (if it has been imported in a PKCS#12 file) with:
signcode -spc mycert.spc -k "MY KEY" file.dll
Replace the name MY KEY with the name of the corresponding private key container. This is the friendly name of the imported PKCS#12 file (the value you gave after the -name parameter).
Q. What about PVK files?
A. I've recently managed to work out the latest PVK format. For more details and OpenSSL conversion tools check out my PVK file information page. Using my PVK conversion program you can generate a PVK file from the PEM encoded private key with:

pvk -in key.pem -topvk -out key.pvk

You would then use this with signcode with:

signcode -spc mycert.spc -v key.pvk file.dll

Using this method there is no need to import or generate the PKCS#12 file at all. Simply use the private keys and certificates converted directly from OpenSSL.

Q. What about signing with keys larger than 512 bits?
A. If you are able, then installing the domestic security patch is the easiest thing to do. If you are not then you can in actual fact still use keys larger than 512 bits. This isn't documented very well: hence my original assumption that this was not possible. The reason you can do this is that MS CryptoAPI (used by the signing tools) allows signing only keys to be larger than 512 bits. Indeed the documentation suggests that the limit is at least 16,384 bits including key generation. This document is not concerned with key generation because it assumes that OpenSSL creates the necessary keys. Anway there are two ways to handle things. Either with a PVK file or import of a PKCS#12 file.

If you wish to use a PVK file (and this is discouraged due to the weak encryption) then you can just use the sig option to create a PVK file with the private key marked as a signature key, future versions of the PVK conversion program will have this option set by default. For example:

pvk -sig -in key.pem -topvk -out key.pvk

If you wish to keep the key in the registry and import a PKCS#12 file then you need version 0.52 or later of my PKCS#12 program. If you supply the keysig option a special attribute is set in the PKCS#12 file and the private key is imported as a signature key. For example:

openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -name "MY CERTIFICATE" -certfile demoCA/cacert.pem -out mycert.p12 -keysig

This keysig option is off by default: this is because signature keys cannot be used for S/MIME encryption.


General issues.

Q. What order do the certificates and keys appear in the output file?
A. They appear in the order they appear in the input file. You can dump just user certificates or CA certificates with the clcerts and cacerts options respectively.
Q. What is the caname option for?
A. This allows a name (friendly name in PKCS#12 jargon) to be associated with each CA certificate in the PKCS#12 file. If you add more than one CA certificate you can use multiple caname arguments to assign a name to each. It was initially useful to work around an MSIE4 bug but this is no longer necessary.

Technical queries.

Q. I want to create and parse PKCS#12 files, how can I do this?
A. There are now two "high level" functions in OpenSSL that do all the hard work, PK12_parse() and PKCS12_create(). PKCS12_parse() was originally written for Celo Communications who have kindly allowed them to be included in the main distribution. Check the documentation in doc/openssl.txt for more details on how to use these functions.
Q. Where can I get technical documentation on this stuff?
A. If you want info about my implementation see docs/pk12api.doc and docs/pkcs12.doc.
Latest PKCS#12 Specification.
Q. What about test vectors for that horrible key generation algorithm?
A. If you compile the code you can uncomment out the  KEYGEN_DEBUG line in crypto/pkcs12/p12_key.c and it will print out info as it goes along. Alternatively here are some sample test vectors.
Q. What encryption is used in the files?
A. Depends on which files you mean. PKCS#12 supports the following encryption algorithms. In addition the PKCS#5 v1.5 modes are possible as well. This also permits the following. The use of PKCS #5 v2.0 would allow the use of arbitrary encryption algorithms.

While OpenSSL can handle PKCS#5 v1.5 and v2.0 in PKCS#12 files other implementations may not.

I've decided to clarify the supported encryption of various implementations with a table.
 
Software and mode. Certificate encryption Private key encryption
MSIE4 (domestic and export versions) PKCS#12 export. 40 bit RC2. 40 bit RC2
MSIE4, 5(domestic and export versions) PKCS#12 import. 40 bit RC2, 3 key triple DES. 40 bit RC2, 3 key triple DES.
MSIE5  PKCS#12 export. 40 bit RC2 3 key triple DES with SHA1 (168 bits)
Netscape Communicator (domestic and export versions) PKCS#12 export 40 bit RC2. 3 key triple DES with SHA1 (168 bits)
Netscape Communicator (export version) PKCS#12 import. 40 bit ciphers only. All.
Netscape Comminicator (domestic or fortified version) PKCS#12 import. All. All.
OpenSSL PKCS#12 code. All. All.

If you want to see for yourself what is used try the info option to pkcs12.

By default the strongest encryption supported by all implementations is used in the pkcs12 application: 3DES for private keys and RC2-40 for certificates. The descert option allows certificates to be encrypted with 3DES as well.

It should be noted that while many versions of Netscape will import files using a variety of algorithms MSIE seems to support 40 bit RC2 and triple DES only.

You can also use the keypbe and certpbe command line options to specify other encryption algorithms for private keys and certificates.

It should be noted that superencryption (that is placing one encrypted structure within another) .may not work with either browser.

As for the OpenSSL output files, the encryption is whatever you set it to (default triple DES).

Q. What's the MAC it keeps saying is OK?

A. This is an integrity check. When used with the correct password it can be used to verify that the file has not been corrupted.
My pkcs12 application (and NS/MSIE) currently uses the same password for integrity (MAC) and privacy (encryption) by default. If you use the twopass option you can set and input separate passwords: such files cannot be imported into current versions of MSIE or NS.

Q. What's this I hear about iteration counts?
A. The algorithm used to generate keys from passwords and the MAC has an optional iteration count. This determines how many times part of the algorithm is repeated. It's a way of slowing down the key derivation process to make it harder to make dictionary attacks on the password. The -info option now prints information about iteration counts.
Q. What iteration counts are used?

A. By default I set both iteration counts to 2048. If you use the -nomaciter option the MAC iteration count is also set to 1 some software such as MSIE4 needs this option because it does not support mac iteration counts. If you use the noiter option the iteration count is set to 1: since this makes dictionary attacks on the password easier this is not recommended.

MSIE5 uses 2000 for the encryption iteration count. If you have the 'enable strong protection' option checked then it uses 2000 for the MAC count otherwise it uses 1 (for compatability with earlier versions of MSIE).

NS will happily import files with MAC and encryption iteration counts.

Q. I'm paranoid. I need a bigger iteration count.
A. Have a look for the _ITER_ definition near the start of pkcs12.c, set it to whatever you like and recompile. Setting this to a huge value is a bad idea because it can adversely slow down the handling of files.
Q. How do I create more complex PKCS#12 files?
You can create PKCS#12 files of arbitrary complexity using the API.
Q. What are the "friendly name" and "local key id" referred to in the output?
A. The "friendly name" is just a user friendly way of referring to a user certificate, it is also the name Netscape puts in its list box when you import. E.g. "My certificate". It is set with the -name parameter to pkcs12. "local key id" is just a string to allow keys and certificates to be matched (same id means matched).
Q. What values are used for these attributes?
A. In my implementation the friendly name is set to the value passed with the -name parameter. The key id is set to the SHA-1 hash of the certificate.

NS uses the name in the list box for the friendly name and the key id is the SHA-1 hash of the certificate.

MSIE uses the key container name (a weird bunch of digits which looks suspiciously like a GUID) for the friendly name and 00 00 00 01 for the key id.

Q. Can PKCS#12 be used for non RSA private keys, for example DSA and DH keys?
A. Yes it can. PKCS#12 uses PKCS#8 for storing private keys but PKCS#8 itself only gives information about RSA. PKCS#11 however extends PKCS#8 and provides a standard for storing DSA and DH private keys using PKCS#8. Netscape follows the PKCS#11 extension to PKCS#8 for DSA private keys. For more information see the PKCS#11 specification.
Q. What do the 40 bit and 128 bit RC2 modes mean, that is what is their key length and number of bits? My key and IV generation seems fine but I have problems decoding 40 bit RC2 encrypted data, whats wrong?
A. The RC2 algorithm takes a key, a key length and a number of bits parameter. They number of bits paramater is also sometimes called the effective key length. What PKCS#12 refers to as 40 bit RC2 is a keylength of 5 bytes and 40 for the number of bits. If you use any different parameters then you will be unable to decrypt the data.
Q. What is this special attribute added to PKCS#12 files to make MS software import keys as signature only?
A. When I closely analysed MS PKCS#12 files used for signing only and key exchange I noticed that the PKCS#8 PrivateKeyInfo structure contained a keyUsage attribute. The object identifier is the same as the keyUsage certificate extensions and the associcated parameter is a BITSTRING. A signature key has the digitalsignature bit set and an exchange key has the dataEncipherment bit set. This corresponds to bits 0 and 3 or the values 0x80 and 0x10 respectively.
Q,. What does the new cspname option do to add a CSP name?
This adds a new attribute to the relevant safebags. It is a BMPString containing the CSP name and the object identifier is 1.3.6.1.4.1.311.17.1
Q. What kind of PKCS#12 files are produced by browsers?
Traditionally a PKCS#12 file contains a private key, its corresponding certificate and one or more CA certificates, it can also contain a MAC for integrity testing.

Some more recent versions of Netscape browsers using PSM can contain multiple private keys and certificates in a single PKCS#12 file. OpenSSL can parse such files and extract all the keys and certificates but not create them (yet).

The PKCS#12 files exported by MSIE follow the traditional rules. However some recent tests show that some versions of MSIE can import much simpler PKCS#12 files, in particular it can handle files without the MAC and even without any certificates. MSIE gives an alert box saying such files are "empty" but still imports the private key into CryptoAPI.


For email details see my contact page.

Back to Home Page