Create a CA (new)
Create the initial directory structure
mkdir -p ~/ca/root_ca/{certs,crl,newcerts,private}
mkdir -p ~/ca/intermediate_ca/{certs,crl,csr,newcerts,private}
mkdir -p ~/ca/server/{certs,crl,csr,newcerts,private}
chmod 700 root_ca/private intermediate_ca/private
echo 1000 > root_ca/serial; echo 1000 > intermediate_ca/serial
echo 1000 > root_ca/crlnumber; echo 1000 > intermediate_ca/crlnumber
:>root_ca/index.txt; :>intermediate_ca/index.txt
Create config files
Create the Root CA config file
Paste the following into ~/ca/root_ca.cnf
# vim: sts=4 sw=4 ts=4 et
# OpenSSL configuration file for Root CA
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./root_ca
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/certs/root_ca.crt
serial = $dir/serial
crlnumber = $dir/crlnumber
private_key = $dir/private/root_ca.key
RANDFILE = $dir/private/.rand
x509_extensions = v3_ca
copy_extensions = copy
default_days = 14600
default_crl_days = 30
default_md = sha512
preserve = no
policy = policy_strict
[ policy_strict ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 4096
default_md = sha512
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
string_mask = utf8only
prompt = yes
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
organizationName = Organization Name
commonName = Common Name
countryName_default =
stateOrProvinceName_default =
localityName_default =
0.organizationName_default =
organizationalUnitName_default =
emailAddress_default =
commonName_default = Pwned Global Root CA
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, keyCertSign
[ v3_intermediate_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, cRLSign, keyCertSign
[ crl_ext ]
authorityKeyIdentifier = keyid:always,issuer
Create the Intermediate CA config file
Paste the following into ~/ca/intermediate_ca.cnf
# vim: sts=4 sw=4 ts=4 et
# OpenSSL configuration file for Intermediate CA
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./intermediate_ca
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/certs/intermediate_ca.crt
serial = $dir/serial
crlnumber = $dir/crlnumber
private_key = $dir/private/intermediate_ca.key
RANDFILE = $dir/private/.rand
x509_extensions = v3_intermediate_ca
copy_extensions = copy
default_days = 3650
default_crl_days = 30
default_md = sha512
preserve = no
policy = policy_loose
[ policy_loose ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 4096
default_md = sha512
distinguished_name = req_distinguished_name
x509_extensions = v3_intermediate_ca
string_mask = utf8only
prompt = yes
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
organizationName = Organization Name
commonName = Common Name
countryName_default =
stateOrProvinceName_default =
localityName_default =
0.organizationName_default =
organizationalUnitName_default =
emailAddress_default =
commonName_default = Pwned Global Intermediate CA
[ v3_intermediate_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, cRLSign, keyCertSign
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[ crl_ext ]
authorityKeyIdentifier = keyid:always,issuer
Create The Server Certificate config file
Paste the following into ~/ca/server.cnf
# vim: sts=4 sw=4 ts=4 et
# OpenSSL configuration file for Server Certificates
[ req ]
default_bits = 2048
default_md = sha256
distinguished_name = req_distinguished_name
req_extensions = v3_req
string_mask = utf8only
prompt = yes
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
organizationName = Organization Name
commonName = Common Name
countryName_default = US
stateOrProvinceName_default = California
localityName_default = Venice Beach
organizationName_default =
commonName_default = www.example.com
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.example.com
DNS.2 = example.com
Create all the certs
Create the Root CA
Create the Root Key
openssl genpkey -aes256 -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out root_ca/private/root_ca.key
Create the Root Certificate
openssl req -config root_ca.cnf -x509 -new -nodes -key root_ca/private/root_ca.key -sha512 -days 14600 -out root_ca/certs/root_ca.crt
Verify the Root Certificate looks good
cat root_ca/certs/root_ca.crt | openssl x509 -text -noout
Create the Intermediate CA
Create the Intermediate Key
openssl genpkey -aes256 -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out intermediate_ca/private/intermediate_ca.key
Create the Intermediate Certificate Sign Request
openssl req -config intermediate_ca.cnf -new -key intermediate_ca/private/intermediate_ca.key -out intermediate_ca/csr/intermediate_ca.csr
Sign the Intermediate CSR with the Root CA
openssl ca -config root_ca.cnf -extensions v3_intermediate_ca -days 3650 -notext -md sha512 -in intermediate_ca/csr/intermediate_ca.csr -out intermediate_ca/certs/intermediate_ca.crt
Verify the Intermediate CA Certificate looks good
cat intermediate_ca/certs/intermediate_ca.crt | openssl x509 -text -noout
Create a Certificate Chain
cat intermediate_ca/certs/intermediate_ca.crt root_ca/certs/root_ca.crt > intermediate_ca/certs/ca_chain.crt
Verify the Certificate Chain looks good
cat intermediate_ca/certs/ca_chain.crt | openssl x509 -text -noout
Create a server (leaf) certificate
Warning
You will need to modify server.cnf to fit your needs
Note
Unlike the Root and Intermediate certs, we don’t encrypt the server key with a password (Notice the missing -aes256 option) because all your applications will require you to enter the password every time you start or restart them
Create a key for your new Server Certificate
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out server/private/server.key
Create a Certificate Signing Request using your new key
openssl req -config server.cnf -new -key server/private/server.key -out server/csr/server.csr
Sign the Server Certificate with the Intermediate CA
openssl ca -config intermediate_ca.cnf -extensions v3_req -days 365 -notext -in server/csr/server.csr -out server/certs/server.crt
Verify the Server Certificate
cat server/certs/server.crt | openssl x509 -text -noout
Verify the Chain of Trust
openssl verify -CAfile intermediate_ca/certs/ca_chain.crt server/certs/server.crt
Create a Full Chain Bundle
cat server/certs/server.crt intermediate_ca/certs/ca_chain.crt > server/certs/server.pem
Verify the Full Chain Bundle
cat server/certs/server.pem | openssl x509 -text -noout