Create a new Certificate Authority or an intermediate CA from your existing PKI.

With open source step-ca or Smallstep Certificate Manager you can create an entirely new private PKI setup or an intermediate CA from your existing PKI. Intermediate CAs (also called subordinate CAs) are used to sign and issue leaf certificates to subscribers. Intermediates aren't generally included in trust stores, making them easier to revoke and rotate, so certificate issuance from an intermediate typically is online and automated.

This tutorial will walk you through three ways of bootstrapping step-ca to create new PKI or an intermediate CA.

About this tutorial

  • Learn how to stand up a new private certificate authority or create an intermediate CA to your existing PKI.
  • Examples include copy/paste code blocks and specific commands for Active Directory (ADCS), AWS Private CA (ACM-PCA), OpenSSL, and CFSSL.
  • When complete, you will have a fully functioning certificate authority or intermediate CA that can issue X.509 or SSH certificates.
  • Estimated effort: Reading time ~3 mins, Lab time ~10 to 60 mins.

Requirements

This tutorial assumes you have initialized and started up a step-cainstance using the steps in Getting Started.

Overview

The Easy Way

If you have your root CA signing key available, run:

$ step ca init --root=[ROOT_CERT_FILE] --key=[ROOT_PRIVATE_KEY_FILE]

Note: The root certificate can be in PEM or DER format, and the signing key can be a PEM file containing a PKCS#1, PKCS#8, or RFC5915 (for EC) key.

The Medium Way

If you have your own root certificate and intermediate certificate and key pair then all you'll need to do is move them to the right locations and update your $(step path)/config/ca.json configuration file.

1. Use step to generate a boilerplate configuration

It's easiest to run step ca init to get the boilerplate configuration in place, then remove or replace these artifacts with new ones that are tied to your existing root CA.

$ step ca init

When you run step ca init we create a couple artifacts under ~/.step/. The important ones for us are:

  • ~/.step/certs/root_ca.crt the CA certificate
  • ~/.step/secrets/root_ca_key the CA signing key
  • ~/.step/certs/intermediate_ca.crt the intermediate CA cert
  • ~/.step/secrets/intermediate_ca_key the intermediate signing key used by step-ca

step-ca does not actually need the root CA signing key. So you can remove that file:

shred -u ~/.step/secrets/root_ca_key

2. Replace step-ca's root CA cert and intermediate CA cert/key with your existing PKI.

$ mv root.crt ~/.step/certs/root_ca.crt $ mv intermediate.crt ~/.step/certs/intermediate_ca.crt $ mv intermediate_ca_key ~/.step/secrets/intermediate_ca_key

Verify that the $(step path)/config/ca.json is pointing to the correct location for each of these files.

That's it! You should now be able to start step-ca and generate X.509 certificates that can be validated and authenticated by any software that trusts your root certificate.

The Secure Way

Let's face it; you probably wouldn't be reading this if you were looking for the easy way. It's bad practice to move private keys around. Below you will find the more complex instructions to "bootstrap from an existing PKI" the right way by generating a CSR, signing it with your existing root, and configuring step-ca to use it.

1. Use step to generate a boilerplate configuration

It's easiest to run step ca init to get the boilerplate configuration in place, then remove or replace these artifacts with new ones that are tied to your existing root CA.

$ step ca init

When you run step ca init we create a couple artifacts under ~/.step/. The important ones for us are:

  • ~/.step/certs/root_ca.crt the CA certificate
  • ~/.step/secrets/root_ca_key the CA signing key
  • ~/.step/certs/intermediate_ca.crt the intermediate CA cert
  • ~/.step/secrets/intermediate_ca_key the intermediate signing key used by step-ca

step-ca does not actually need the root CA signing key. So you can remove that file:

rm ~/.step/secrets/root_ca_key

2. Replace step-ca's root CA cert with your existing root certificate and generate a new signing key and intermediate certificate.

$ mv </path/to/your/existing/root.crt> ~/.step/certs/root_ca.crt

Now you need to generate a new signing key and intermediate certificate signed by your existing root CA. To do that, we can use the step certificate create subcommand to generate a certificate signing request (CSR) that we'll have your existing root CA sign, producing an intermediate certificate.

To generate those artifacts run:

step certificate create "Intermediate CA Name" intermediate.csr intermediate_ca_key --csr

3. Transfer the CSR file and get it signed.

Now, you will need to transfer the CSR (intermediate.csr) file to your existing root CA and get it signed. Below we have examples of how to do this using step, Active Directory Certificate Services, AWS Certificate Manager Private CA, OpenSSL, and CFSSL.

Use step to sign your intermediate CSR

step certificate sign --profile intermediate-ca intermediate.csr root.crt root.key

Active Directory Certificate Services

certreq -submit -attrib "CertificateTemplate:SubCA" intermediate.csr intermediate.crt

AWS Certificate Manager Private CA

You can now use the following python script that uses issue-certificate to process the CSR:

import boto3 import sys AWS_CA_ARN = '[YOUR_PRIVATE_CA_ARN]' csr = ''.join(sys.stdin.readlines()) client = boto3.client('acm-pca') response = client.issue_certificate( CertificateAuthorityArn=AWS_CA_ARN, Csr=csr, SigningAlgorithm='SHA256WITHRSA', TemplateArn='arn:aws:acm-pca:::template/SubordinateCACertificate_PathLen1/V1', Validity={ 'Value': 5, 'Type': 'YEARS' } ) print(f"Creating certificate with ARN {response['CertificateArn']}...", file=sys.stderr, end='') waiter = client.get_waiter('certificate_issued') waiter.wait( CertificateAuthorityArn=AWS_CA_ARN, CertificateArn=response['CertificateArn'] ) print('done.', file=sys.stderr) response = client.get_certificate( CertificateArn=response['CertificateArn'], CertificateAuthorityArn=AWS_CA_ARN ) print(response['Certificate'])

To run it, fill in the ARN of your CA and run:

$ python issue_certificate.py < intermediate.csr > intermediate.crt

OpenSSL

openssl ca -config [ROOT_CA_CONFIG_FILE] \
  -extensions v3_intermediate_ca \
  -days 3650 -notext -md sha512 \
  -in intermediate.csr \
  -out intermediate.crt

CFSSL

For CFSSL you'll need a signing profile that specifies a 10-year expiry:

$ cat > ca-smallstep-config.json <<EOF { "signing": { "profiles": { "smallstep": { "expiry": "87660h", "usages": ["signing"] } } } } EOF

Now use that config to sign the intermediate certificate:

$ cfssl sign -ca ca.pem \ -ca-key ca-key.pem \ -config ca-smallstep-config.json \ -profile smallstep -csr intermediate.csr | cfssljson -bare

This process will yield a signed intermediate.crt certificate (or cert.pem for CFSSL). Transfer this file back to the machine running step-ca.

4. Replace the intermediate.crt and signing key

Finally, replace the intermediate .crt and signing key produced by step ca init with the new ones we just created:

$ mv intermediate.crt ~/.step/certs/intermediate_ca.crt $ mv intermediate_ca_key ~/.step/secrets/intermediate_ca_key

That's it! You should now be able to start step-ca and generate X.509 certificates that can be validated and authenticated by any software that trusts your root certificate.