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.
# 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.
openssl genrsa -aes256 -out /root/ca/root/private/root.key.pem 4096
chmod 0400 /root/ca/root/private/root.key.pem
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.