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
It's easiest to run step ca init
to get the boilerplate configuration in place, then remove or replace the auto-generated artifacts with new ones that are tied to your existing root CA.
$ 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
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
, 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
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 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-ca
s.
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.