Setup Root CA

The root CA should never be used other than to create or revoke intermediate CAs. It should always be kept offline and secured once intermediate CAs are setup. A compromise of the root CA key will compromise all child certificates.

Create Root CA OpenSSL Configuration

A good default is here. This configuration should only contain relevant sections for the required Root CA actions. Configuration file must be specified when issuing Root CA operations otherwise the systemwide openssl.conf default configuration will be used.

0600 root root /root/ca/root/root.ca
# OpenSSL root CA configuration file.
# Stripped down to just Root CA functionality.
# https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html

[ ca ]
default_ca                     = CA_default

[ CA_default ]
# Directory and file locations.
dir                            = /root/ca/root
certs                          = $dir/certs
crl_dir                        = $dir/crl
new_certs_dir                  = $dir/newcerts
database                       = $dir/index.txt
serial                         = $dir/serial
RANDFILE                       = $dir/private/.rand

# The root key and root certificate.
private_key                    = $dir/private/root.key.pem
certificate                    = $dir/certs/root.cert.pem

# For certificate revocation lists.
crlnumber                      = $dir/crlnumber
crl                            = $dir/crl/root.crl.pem
crl_extensions                 = crl_ext
default_crl_days               = 375

default_md                     = sha512
name_opt                       = ca_default
cert_opt                       = ca_default
default_days                   = 375
preserve                       = no
policy                         = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
countryName                    = match
stateOrProvinceName            = match
organizationName               = match
organizationalUnitName         = optional
commonName                     = supplied
emailAddress                   = optional

[ req ]
# Applied when creating / signing certificates.
default_bits                   = 4096
distinguished_name             = req_distinguished_name
string_mask                    = utf8only
default_md                     = sha512
x509_extensions                = v3_ca

[ req_distinguished_name ]
# CSR information required, prompts and defaults.
countryName                    = Country Name (2 letter code)
stateOrProvinceName            = State or Province Name
localityName                   = Locality Name
0.organizationName             = Organization Name
organizationalUnitName         = Organizational Unit Name
commonName                     = Common Name
emailAddress                   = Email Address

# Default values for certification generation.
countryName_default            = XX
stateOrProvinceName_default    = XX
localityName_default           = XX
0.organizationName_default     = {CA NAME}
organizationalUnitName_default = {CA NAME} Certificate Authority
commonName_default             = {CA NAME} Root CA
emailAddress_default           = XX

[ v3_ca ]
# Root CA extenstions: man x509v3_config '-extensions v3_ca'
subjectKeyIdentifier           = hash
authorityKeyIdentifier         = keyid:always,issuer
basicConstraints               = critical, CA:true
keyUsage                       = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Intermediate CA extensions: man x509v3_config '-extensions v3_intermediate_ca'
subjectKeyIdentifier           = hash
authorityKeyIdentifier         = keyid:always,issuer
basicConstraints               = critical, CA:true, pathlen:0
keyUsage                       = critical, digitalSignature, cRLSign, keyCertSign

[ crl_ext ]
# Certificate revocation list extensions: man x509v3_config
authorityKeyIdentifier         = keyid:always

[ ocsp ]
# OCSP signing certificate extensions: man ocsp
basicConstraints               = CA:FALSE
subjectKeyIdentifier           = hash
authorityKeyIdentifier         = keyid,issuer
keyUsage                       = critical, digitalSignature
extendedKeyUsage               = critical, OCSPSigning

Create Root CA Private Key and Certificate

Should be done on an air-gapped machine and stored encrypted offline once the intermediate CA is setup. Root CA should rarely be used.

Create the private key.
openssl genrsa -aes256 -out /root/ca/root/private/root.key.pem 4096
chmod 0400 /root/ca/root/private/root.key.pem
Create the Root CA Certficate.
openssl req -config /root/ca/root/root.ca -key /root/ca/root/private/root.key.pem -new -x509 -days 7300 -sha512 -extensions v3_ca -out /root/ca/root/certs/root.cert.pem
chmod 444 /root/ca/root/certs/root.cert.pem
openssl x509 -noout -text -in /root/ca/root/certs/root.cert.pem
  • A long lifetime (7300 days, 20 years) for an offline Root CA is OK. When the Root CA expires, all child certificates become invalid.

  • Defaults from root.ca will autofill CA certificate fields.