• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

Mister PKI

SSL Certificates * SSL Tools * Certificate Decoder

  • Buy SSL Certificates
  • Blog
  • OpenSSL
  • Keytool
  • SSL Tools
  • Donate

pkcs12

December 1, 2022 by Mister PKI Leave a Comment

A pkcs12 keystore is commonly used for both S/MIME User Certificates and SSL/TLS Server Certificates. The keystore may contain both private keys and their corresponding certificates with or without a complete chain. The keystore’s purpose is to store the credential of an identity, being a person, client, or server. Common file extensions include .p12 or .pfx for clarity, but may be anything you choose.

If you are in the market of purchasing a new SSL Certificate, start here.

RFC 7292 goes into much much much more detail about the PKCS #12 standard: https://tools.ietf.org/html/rfc7292

Unfortunately, there is not 100% coverage in all commands for maintaining PKCS #12 keystores in either OpenSSL or the Java Keytool so you must use both for comprehensive coverage of all the functions for maintaining your keystore.

The PKCS12 keystore is non-proprietary unlike the JKS and is becoming the most commonly used format. In fact, if you choose to generate a JKS keystore with the Java Keytool you will receive the following warning:

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format

With that said, this post strives to provide examples to common commands used to create and manage PKCS12 keystores that will hopefully make your life on the job a bit easier.

For numerous examples of converting to and from pkcs12 that may not be covered in this article you can read more here.

How do I create a keystore with a self-signed certificate using the java keytool?

Using the Java Keytool, run the following command to create the keystore with a self-signed certificate:

keytool -genkey \
  -alias somealias \
  -keystore keystore.p12 \
  -storetype PKCS12 \
  -keyalg RSA \
  -storepass somepass \
  -validity 730 \
  -keysize 4096

Keystore generation option breakdown:

Keytool optionDescription
-genkeyGenerate keystore
-aliasAlias of the generated private key entry
-keystoreKeystore file to be created
-storetypeType of keystore. PKCS12 in this example
-keyalgKey algorithm of key entry to be generated
-storepassPassword to set on both the key entry and keystore
-validityValidity of the certificate associated with the key entry
-keysizeSize of the generated private key in bits
Keytool genkey options for PKCS12 keystore

Watch the video below for a visual example of generating a pkcs12 keystore with keytool. Or head over to our focused post on how to generate a keystore with the java keytool.

java keytool generate keystore and self-signed certificate

How do I create a PKCS12 keystore from an existing private key and certificate using openssl?

While some configurations require the certificate and private key to be in separate files with pointers to them, it is becoming more common for configuration to point to a keystore instead. To create the keystore from an existing private key and certificate, run the following command. Note that if the certificate.pem file contains the entire certificate chain it will be imported into the keystore as part of the private key entry. Usually this is what you want. Alternatively, you can import the chain in a later step detailed below with the heading “How do I update the trust chain in an existing keystore for a specific keystore entry?”.

openssl pkcs12 \
  -export \
  -in certificate.pem \
  -inkey key.pem \
  -out keystore.p12
OpenSSL OptionDescription
pkcs12Create pkcs12 formatted keystore
-exportExport the keystore to a file
-inThe existing certificate file
-inkeyThe existing key file
-outThe name of the newly created pkcs12 keystore
OpenSSL options for creating PKCS12 keystore from an existing private key and certificate

How do I convert a JKS keystore to PKCS12?

This example uses the importkeystore command. For more details on this command head over to our focused post on importing an existing keystore into another keystore. To convert a Java Keystore to a PKCS #12 Keystore (.jks to .p12), run the following command:

keytool -importkeystore \
  -srckeystore keystore.jks \
  -destkeystore keystore.p12 \
  -srcstoretype JKS \
  -deststoretype PKCS12 \
  -deststorepass password \
  -srcalias alias \
  -destalias alias
Keytool OptionsDescription
-importkeystoreImport existing keystore into new keystore
-srckeystoreThe keystore to be imported
-destkeystoreThe keystore to accept the import
-srcstoretypeThe type of keystore to be imported
-deststoretypeThe type of keystore to accept the import
-deststorepassThe password of the new keystore
-srcaliasThe alias to be imported
-destaliasThe alias to import to
JKS to PKCS12 keystore conversion example

How do I convert a PKCS12 keystore to JKS?

To convert a PKCS12 keystore to JKS, run the following command:

keytool -importkeystore \
  -srckeystore example.p12 \
  -srcstoretype PKCS12 \
  -destkeystore example.jks \
  -deststoretype JKS

Read more about using java keytool to import a keystore into another keystore.

How do I change the password of a PKCS12 keystore?

To change the password of a PKCS #12 keystore (make sure to also change the password of the key, if not, the keystore will be corrupt), run the following commands:

First, change the keystore password:

keytool -storepasswd -keystore keystore.p12

Finally, change the key password in that keystore for each alias:

keytool -keypasswd -alias alias -keystore keystore.p12

How do I change an alias name in a keystore?

When generating a keystore, the default alias is 1 if not explicitly set. This default value may vary based on the software used to generate the keystore. We have a focused post on changing an alias here for even more details on this command. To change the alias, run the following command:

keytool -changealias -keystore keystore.p12 -alias alias

How do I list the contents of a keystore?

It is useful and recommended to verify any changes made to a keystore. The simplest way is to just list the contents. To list the contents of the PKCS #12 keystore run the following command:

keytool -list -v -keystore keystore.p12

How do I extract a private key from a keystore using openssl?

Some software requires a stand alone private key instead of a keystore for authentication, signing, etc. To extract the private key from a keystore, run the following command:

openssl pkcs12 -in keystore.p12 -nocerts -nodes

Note that secret keys are not supported with openssl in a pkcs12 keystore. If you attempt to extract a secret key entry you will receive the following exception: Warning unsupported bag type: secretBag.

View the video on extracting a private key from a keystore with OpenSSL for a step by step walk through.

Extract a private key from a pkcs12 keystore with openssl

How do I extract certificates from a keystore using openssl?

Similar to requiring a stand alone key, some software requires stand alone certificate files to be used instead of a keystore. To extract a certificate or certificate chain from a PKCS12 keystore using openssl, run the following command:

openssl pkcs12 -in example.p12 -nokeys

Where -in example.p12 is the keystore and -nokeys means only extract the certificates and not the keys.

How do I update the trust chain in an existing keystore for a specific keystore entry?

You may find it useful or necessary to update a trust chain to an existing keystore entry. For example, in the event of an expiring trust chain due to a cross signed root or intermediate, you may have an expiring chain installed and need to replace it (like with the AddTrust root expiration) with Sectigo. To update the trust chain for a given alias in a pkcs12 keystore, run the following command:

keytool -import \
  -trustcacerts \
  -alias alias_to_be_updated \
  -file chain.pem \
  -keystore keystore.p12

Where -trustcacerts means the trust chain is being added to the existing entry, -alias alias_to_be_updated is the entry being updated, -file chain.pem is the complete certificate chain including the end entity certificate, all intermediate certificates, and the root certificate, and -keystore keystore.p12 is the keystore being updated.

If you encounter Error: “java.lang.exception: failed to establish chain from reply” it is likely you have not included the correct chain or the complete chain, including the root. Also, check the formatting of the chain as it is easy to miss a character in the header and/or footer of each certificate in the chain.

How to create pkcs12 truststore using OpenSSL

The key (no pun intended) to creating a pkcs12 (.p12 or .pfx) truststore or keystore is to use the -nokeys flag. Run the following command to import only a certificate into a new keystore:

openssl pkcs12 -export -out test.pfx -nokeys -in test.pem

If you encounter the following error then that means you did not supply the -nokeys flag.

unable to load private key
140022995109184:error:0909006C:PEM routines:get_name:no start line:../crypto/pem/pem_lib.c:745:Expecting: ANY PRIVATE KEY

Keystore Exceptions – PKCS12, JKS, or any type

When operating on a keystore, you will likely enter invalid input or find your keystore in a corrupt state at some point. Here are some common exceptions you may see.

When listing a keystore (and likely other operations), you may encounter this error:

keytool error: java.security.KeyStoreException: This keystore does not support probing and must be loaded with a specified type

keytool error: java.security.KeyStoreException: This keystore does not support probing and must be loaded with a specified type
java.security.KeyStoreException: This keystore does not support probing and must be loaded with a specified type
at java.base/java.security.KeyStore.getInstance(KeyStore.java:1816)
at java.base/java.security.KeyStore.getInstance(KeyStore.java:1687)
at java.base/sun.security.tools.keytool.Main.doCommands(Main.java:924)
at java.base/sun.security.tools.keytool.Main.run(Main.java:409)
at java.base/sun.security.tools.keytool.Main.main(Main.java:402)

To move past this error, simply specify the keystore type with -storetype PKCS12 (or the store type of your keystore) in your command.

Create PKCS12 keystore with Java

There are many reasons you may need to generate a keystore with Java instead of on the command line. As part of your Java application you may be issuing certificates, keys, keystores, etc. and need to generate a keystore programmatically. Additionally it may be useful to generate a new keystore in a test environment to not have a static keystore sitting around that will likely contain expired certificates at some point.

Here is some Java code to programmatically create the Keystore. For the complete example, review the GitHub project at https://github.com/misterpki/generate-keystore

public static KeyStore generatePKCS12KeyStore(final String password)
    throws KeyStoreException, NoSuchAlgorithmException, IOException, CertificateException, OperatorCreationException
  {
    final KeyStore keyStore = KeyStore.getInstance("PKCS12");
    keyStore.load(null, password.toCharArray());
    // Create Symmetric key entry
    final KeyGenerator aesGenerator = KeyGenerator.getInstance("AES");
    aesGenerator.init(128);
    final KeyStore.SecretKeyEntry aesSecretKey = new KeyStore.SecretKeyEntry(aesGenerator.generateKey());
    final KeyStore.ProtectionParameter aesSecretKeyPassword =
      new KeyStore.PasswordProtection(password.toCharArray());
    // Add symmetric key to keystore
    keyStore.setEntry("symm-key", aesSecretKey, aesSecretKeyPassword);
    // Create Asymmetric key pair
    final KeyPair asymmetricKeys = KeyPairGenerator.getInstance("RSA").generateKeyPair();
    final KeyStore.PrivateKeyEntry privateKey =
      new KeyStore.PrivateKeyEntry(
        asymmetricKeys.getPrivate(),
        new X509Certificate[]{generateX509Certificate(asymmetricKeys)});
    final KeyStore.ProtectionParameter privateKeyPassword =
      new KeyStore.PasswordProtection(password.toCharArray());
    // Add asymmetric key to keystore
    keyStore.setEntry("asymm-key", privateKey, privateKeyPassword);
    return keyStore;
  }

Another example (not recommended) but for general demonstration.

package com.misterpki;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
public class Main {
  public static void main(String[] args) throws Exception {
    try (final FileOutputStream stream = new FileOutputStream("keyStore.p12")) {
      generatePKCS12().store(stream, "changeit".toCharArray());
    }
  }
  private static KeyStore generatePKCS12() throws NoSuchProviderException,
    NoSuchAlgorithmException,
    KeyStoreException,
    InvalidKeyException,
    IOException,
    CertificateException,
    SignatureException
  {
    final KeyStore keyStore = KeyStore.getInstance("PKCS12");
    keyStore.load(null, new char[0]);
    final CertAndKeyGen certGenerator = new CertAndKeyGen("RSA", "SHA256WithRSA", null);
    certGenerator.generate(4096);
    //validity of 1 year
    final long validSecs = (long) 365 * 24 * 60 * 60;
    final X509Certificate certificate = certGenerator.getSelfCertificate(
      new X500Name("CN=some_name,O=some_org,L=some_city,C=some_country"), validSecs);
    keyStore.setKeyEntry("alias",
      certGenerator.getPrivateKey(),
      "changeit".toCharArray(),
      new X509Certificate[]{certificate});
    return keyStore;
  }
}

Conclusion

Please comment with questions and suggestions for additional pkcs12 openssl and java keytool commands that may be helpful so that we may provide as valuable content as possible.

Read all blog content.

keytool,  openssl,  SSL Certificates

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

Popular Posts

PKCS12

openssl s_client

Keytool

Keytool list

ECDSA vs RSA

OpenSSL

PKCS7

Certificate Decoder

Buy SSL Certificates

The SSL Store

Comodo Store

Sectigo Store

RapidSSL

Recent Posts

  • Proxy Addresses Active Directory
  • Windows Private Key Permissions
  • Install .NET 3.5 on Windows Server 2019
  • Netscaler SSL Redirect
  • How to mount NFS share on Linux

Footer

  • Twitter
  • YouTube

Pages

  • About Mister PKI
  • Blog
  • Compare and Buy Affordable PKI Certificates
  • Contact Us
  • Full Disclosure
  • Privacy Policy
  • SSL Tools – Certificate Decoder and Certificate Checker

Copyright © 2023