Creating a custom Public Key Infrastructure (PKI) with OpenSSL

How to create a custom PKI Infrastructure with root ca and intermediate ca with openssl.

Directory structure that holds root ca and intermediate ca PKI files. This structure separates the root CA from the intermediate CA, enhancing security by keeping the root CA offline.

mkdir -p ~/ca-tomdus/{certs,crl,newcerts,private}
chmod 700 ~/ca-tomdus/private
touch ~/ca-tomdus/db/index
openssl rand -hex 16 > ~/ca-tomdus/serial

mkdir -p ~/ca-tomdus/intermediate/{certs,crl,newcerts,private}
chmod 700 ~/ca-tomdus/intermediate/private
touch ~/ca-tomdus/intermediate/db/index
openssl rand -hex 16 > ~/ca-tomdus/intermediate/serial

Create ca-tomdus.conf openssl configuration file.

[default]
name = tomdus-root-ca
domain_suffix = tomdus.lab
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align

[ca_dn]
countryName = "DE"
organizationName = "tomdus"
commonName = Common Name (FQDN or YOUR name)
commonName_max = 64

[ca_default]
home = ~/ca-tomdus/intermediate
certs = $home/certs
database = $home/db/index
serial = $home/db/serial
crlnumber = $home/db/crlnumber
certificate = $home/$name.crt
private_key = $home/private/$name.key
RANDFILE = $home/private/random
new_certs_dir = $home/certs
unique_subject = no
copy_extensions = copy
default_days = 3650
default_crl_days = 365
default_md = sha256
policy = policy_c_o_match

[policy_c_o_match]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[req]
default_bits = 4096
encrypt_key = no
default_md = sha256
utf8 = yes
string_mask = utf8only
prompt = no
distinguished_name = ca_dn

[root_ca_ext]
basicConstraints = critical,CA:true
authorityKeyIdentifier = keyid:always,issuer
keyUsage = critical,keyCertSign,cRLSign,digitalSignature
subjectKeyIdentifier = hash


[sub_ca_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:true,pathlen:0
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,keyCertSign,cRLSign,digitalSignature
nameConstraints = @name_constraints
subjectKeyIdentifier = hash

[crl_info]
URI.0 = $crl_url

[issuer_info]
caIssuers;URI.0 = $aia_url

[name_constraints]
permitted;DNS.0=tomdus.lab
permitted;DNS.1=*.tomdus.dev
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0


[server_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,digitalSignature,keyEncipherment
subjectKeyIdentifier = hash

Generate root CA key and certificate

Change in ca-tomdus.conf  from ~/ca-tomdus/intermediate to ~/ca-tomdus and copy_extensions = copy to copy_extensions = none

openssl genpkey -algorithm RSA -out ~/ca-tomdus/private/tomdus-root-ca.key -aes256 -pkeyopt rsa_keygen_bits:4096
chmod 400 ~/ca-tomdus/private/tomdus-root-ca.key
openssl req -config ~/ca-tomdus/ca-tomdus.conf -key ~/ca-tomdus/private/tomdus-root-ca.key -new -x509 -days 3650 -sha256 -extensions root_ca_ext -out ~/ca-tomdus/certs/tomdus-root-ca.crt
Generate intermediate CA key and certificate
openssl genpkey -algorithm RSA -out ~/ca-tomdus/intermediate/private/tomdus-ca.key -aes256 -pkeyopt rsa_keygen_bits:4096
chmod 400 ~/ca-tomdus/intermediate/private/tomdus-ca.key

Generate CSR

openssl req -config ~/ca-tomdus/ca-tomdus.conf -new -key ~/ca-tomdus/intermediate/private/tomdus-ca.key -out ~/ca-tomdus/intermediate/csr/tomdus-ca.csr

Sign CSR with root CA

openssl ca -config ~/ca-tomdus/ca-tomdus.conf -extensions sub_ca_ext -days 3650 -md sha256 -in ~/ca-tomdus/intermediate/csr/tomdus-ca.csr -out ~/ca-tomdus/intermediate/certs/tomdus-ca.crt

Sample Code: https://gitlab.com/tomdus/pki-infrastructure/