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

Mister PKI

All things PKI, HTTPS, SSL, TLS, Digital Certificates

  • Buy SSL Certificates
  • Blog
  • Java Keytool
  • OpenSSL
  • Certificate Decoder
  • Donate

pkcs12

February 11, 2021 by Mister PKI Leave a Comment

A pkcs12 keystore is commonly used for both S/MIME User Certificates and SSL/TLS Server Certificates. They 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. The file extension can be either .p12 or .pfx.

RFC 7292 goes into much much much more detail: 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.

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

java keytool generate keystore and self-signed certificate

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

To create the keystore from an existing private key and certificate, run the following command:

openssl pkcs12 -export -in certificate.pem -inkey key.pem -out keystore.p12

Where pkcs12 is the openssl pkcs12 utility, -export means to export to a file, -in certificate.pem is the certificate and -inkey key.pem is the key to be imported into the keystore. -out keystore.p12 is the keystore file.

How do I convert a JKS keystore to PKCS12?

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

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.

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:

keytool -storepasswd -keystore keystore.p12
keytool -keypasswd -alias alias -keystore keystore.p12

To change the alias, run the following (the default alias is 1):

keytool -changealias -keystore keystore.p12 -alias alias

To list the contents of the PKCS #12 keystore:

keytool -list -v -keystore keystore.p12

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

To extract the private key:

openssl pkcs12 -in keystore.p12 -nocerts -nodes

Extract a private key from a pkcs12 keystore with openssl

How do I extract certificates from a keystore using openssl?

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). 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 root, 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.

Keystore Exceptions – PKCS12, JKS, or any type

When operating on a keystore, you will likely enter invalid input or find your keystore in a confusing 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

Here’s 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;
  }
}

Please comment and provide 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.

Uncategorized

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

SSL/TLS Certificate Small Square (200 x 200)

Recent Posts

  • keytool delete alias – How to delete an alias from a keystore
  • keytool alias -changealias – How to change a private key alias
  • SSL Certificate Expiration and SSL Certificate Renewal
  • What are SSL certificates?
  • Java SecureRandom

Footer

  • Twitter
  • YouTube

Copyright © 2021 · Designed by North Flow Tech