Use step-ca with your existing CA

Need to extend or migrate from an existing CA to a Smallstep CA?

With this tutorial in hand, you can extend your current PKI by issuing a new intermediate CA (aka subordinate CA) from your existing root or intermediate CA. You'll configure step-ca to issue leaf certificates (aka end-entity certificates) from the new intermediate. This allows step-ca to run independently of your existing CA, while still issuing certificates trusted by your existing clients.

This tutorial covers three ways of bootstrapping a Smallstep CA using an existing PKI.

About this tutorial

  • Explains how to sign a new intermediate CA from an existing CA
  • Examples include 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 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-ca instance using the steps in Getting Started. You'll also need the ability to sign a new intermediate CA using your existing CA. You can use your existing root or intermediate CA to sign the new intermediate CA.

Overview

The Easy Way

Let's configure step ca to sign a new intermediate for itself using your existing root CA.

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

$ step ca init

When you run step ca init, it creates artifacts under $STEPPATH (by default, $HOME/.step). The important ones for us are:

  • $STEPPATH/certs/root_ca.crt the CA certificate
  • $STEPPATH/secrets/root_ca_key the CA signing key
  • $STEPPATH/certs/intermediate_ca.crt the intermediate CA cert
  • $STEPPATH/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 path)/secrets/root_ca_key

2. Import your existing PKI

$ mv root.crt $(step path)/certs/root_ca.crt
$ mv intermediate.crt $(step path)/certs/intermediate_ca.crt
$ mv intermediate_ca_key $(step path)/secrets/intermediate_ca_key

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

You may also wish to delete $(step path)/config/defaults.json, if it exists, and re-run step ca bootstrap with your new Root CA fingerprint.

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

$ step ca init

When you run step ca init, it creates artifacts under $STEPPATH (by default, $HOME/.step). The important ones for us are:

  • $STEPPATH/certs/root_ca.crt the CA certificate
  • $STEPPATH/secrets/root_ca_key the CA signing key
  • $STEPPATH/certs/intermediate_ca.crt the intermediate CA cert
  • $STEPPATH/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 path)/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/existing/root.crt $(step path)/certs/root_ca.crt

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 path)/certs/intermediate_ca.crt
$ mv intermediate_ca_key $(step path)/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.

FAQs

Can I have multiple intermediate CAs?

Sure. Let's say you have a longer path of intermediate CAs:

Existing Root -> Intermediate 1 -> Intermediate 2 -> step-ca Intermediate -> Leaf Certificate

In this setup, you are creating the step-ca intermediate. For this to work, ensure that you're signing your a step-ca intermediate using Intermediate 2.

For this to work, your $(step path)/certs/intermediate_ca.crt file should be a PEM bundle, in this order:

  • step-ca Intermediate
  • Intermediate 2
  • Intermediate 1

It is critical that the step-ca intermediate come first in this file.

Finally, $(step path)/secrets/intermediate_ca_key will be the signing key for step-ca Intermediate.

Can I configure step-ca to sign X.509 leaf certificates from a root CA?

No. Intermediate CAs add a valuable layer of security and indirection to any PKI. Smallstep CA software requires the use of one or more intermediate CAs.

Can I have multiple signing CAs?

Sure. Each step-ca instance will only sign using one intermediate CA, however. If you want multiple signing CAs, you'll need to run multiple step-cas.

Instead of signing a new intermediate, can I have my existing online CA perform signing operations on behalf of step-ca clients?

Maybe. It depends on which CA software you're using. You can configure step-ca to run as a Registration Authority (RA). In this mode, your existing CA continues to sign certificates, while your step-ca (running in RA mode) acts as a front-end interface to your existing CA.

Last updated on November 11, 2024