Creating X.509 Certificates with OpenSSL
This guide describes how to create X.509 certificates with OpenSSL.
For a more streamlined workflow, see creating X.509 certificates with Peridio.
Prerequisites
- OpenSSL CLI.
- Last tested with version 3.0.4 21 Jun 2022.
To inspect any private key, certificate signing request, or certificate you create in this guide, reference X.509.
Create Certificates
Some of the commands below will reference an openssl.cnf
file, you must create this with the contents described at Appendix A.
The openssl.cnf
file requires, and points to the paths of, one additional file to track created certificates and one additional directory to store certificates historically. You must create them:
touch database.txt
mkdir certificates
Note that when creating certificates with the openssl ca
command that it will write the same created certificate file twice, once to the certificates
directory where the name will be the serial number in hex with .pem appended, and once to the calling directory with the name specified by the -out
option of the command.
Private keys are sensitive components of a public key infrastructure. If they are leaked the entire downstream chain of trust is compromised.
The -startdate
and -enddate
options should be specified cautiously as they dictate when the certificate will be valid for. The impact of a certificate not being valid yet or having already expired is dependent on the parties interacting with it.
For information regarding how Peridio interacts with certificates reference CA Certificates and Device Certificates.
Root
For context, reference X.509.
Create a Private Key
For context, reference cli-x509-create.
openssl ecparam \
-genkey \
-name prime256v1 \
-out root-private-key.pem
Create a Certificate Signing Request
For context, reference openssl-req.
openssl req \
-config openssl.cnf \
-key root-private-key.pem \
-new \
-out root-certificate-signing-request.pem \
-section root_certificate_authority_req \
-subj "/CN=unique-root-name"
Create a Certificate
For context, reference openssl-ca.
You must fill in the -startdate
and -enddate
values.
openssl ca \
-batch \
-config openssl.cnf \
-enddate YYYYMMDDHHMMSSZ \
-extensions root_certificate_authority_extensions \
-in root-certificate-signing-request.pem \
-keyfile root-private-key.pem \
-out root-certificate.pem \
-selfsign \
-startdate YYYYMMDDHHMMSSZ
Intermediate
For context, reference X.509 intermediate.
Create a Private Key
For context, reference openssl-ecparam.
openssl ecparam \
-genkey \
-name prime256v1 \
-out intermediate-private-key.pem
Create a Certificate Signing Request
For context, reference openssl-req.
openssl req \
-key intermediate-private-key.pem \
-new \
-out intermediate-certificate-signing-request.pem \
-subj "/CN=unique-intermediate-name"
Create a Certificate
For context, reference openssl-ca.
You must fill in the -startdate
and -enddate
values.
openssl ca \
-batch \
-cert root-certificate.pem \
-config openssl.cnf \
-enddate YYYYMMDDHHMMSSZ \
-extensions intermediate_certificate_authority_extensions \
-in intermediate-certificate-signing-request.pem \
-keyfile root-private-key.pem \
-out intermediate-certificate.pem \
-startdate YYYYMMDDHHMMSSZ
End-Entity Certificate
For context, reference X.509 end entity.
Create a Private Key
For context, reference openssl-ecparam.
openssl ecparam \
-genkey \
-name prime256v1 \
-out end-entity-private-key.pem
Create a Certificate Signing Request
For context, reference openssl-req.
openssl req \
-key end-entity-private-key.pem \
-new \
-out end-entity-certificate-signing-request.pem \
-subj "/CN=unique-end-entity-name"
Create a Certificate
For context, reference openssl-ca.
You must fill in the -startdate
and -enddate
values.
openssl ca \
-batch \
-cert intermediate-certificate.pem \
-config openssl.cnf \
-enddate YYYYMMDDHHMMSSZ \
-extensions end_entity_certificate_extensions \
-in end-entity-certificate-signing-request.pem \
-keyfile intermediate-private-key.pem \
-out end-entity-certificate.pem \
-startdate YYYYMMDDHHMMSSZ
Appendix
A - openssl.cnf
When creating certificates and certificate signing requests there is often a set of common extensions you wish to include. It is convenient to enumerate these extensions in a config file for ease of maintenance and referenceability.
In this guide, we use the following config referenced as openssl.cnf
.
#
# ca
#
[ ca ]
default_ca=default_ca
[ default_ca ]
database=database.txt
default_days=0
default_md=SHA256
email_in_dn=no
new_certs_dir=certificates
policy=default_policy
rand_serial=yes
unique_subject=no
x509_extensions=root_certificate_authority_extensions
[ default_policy ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
#
# extensions
#
[ root_certificate_authority_extensions ]
basicConstraints=critical,CA:TRUE,pathlen:1
extendedKeyUsage=serverAuth,clientAuth
keyUsage=critical,digitalSignature,keyCertSign,cRLSign
subjectKeyIdentifier=hash
[ intermediate_certificate_authority_extensions ]
authorityKeyIdentifier=keyid:always
basicConstraints=critical,CA:TRUE,pathlen:0
extendedKeyUsage=serverAuth,clientAuth
keyUsage=critical,digitalSignature,keyCertSign,cRLSign
subjectKeyIdentifier=hash
[ end_entity_certificate_extensions ]
authorityKeyIdentifier=keyid:always
extendedKeyUsage=clientAuth
keyUsage=critical,digitalSignature
subjectKeyIdentifier=hash
For a comprehensive understanding of what the above configuration is doing, one should exhaustively read all of this guide's References.
References
config
OpenSSL's CONF library configuration files, reference https://www.openssl.org/docs/man3.0/man5/config.html.
openssl-ca
OpenSSL's sample minimal CA application, reference https://www.openssl.org/docs/man3.0/man1/openssl-ca.html.
openssl-ecparam
OpenSSL's EC parameter manipulation and generation command, reference https://www.openssl.org/docs/man3.0/man1/openssl-ecparam.html.
openssl-req
OpenSSL's PKCS#10 certificate request and certificate generating command, reference https://www.openssl.org/docs/man3.0/man1/openssl-req.html.
openssl-x509
OpenSSL's certificate display and signing command, reference https://www.openssl.org/docs/man3.0/man1/openssl-x509.html.
RFC 4158
Internet X.509 Public Key Infrastructure: Certification Path Building, reference https://datatracker.ietf.org/doc/html/rfc4158.
RFC 5280
Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile, reference https://datatracker.ietf.org/doc/html/rfc5280.
x509v3_config
OpenSSL's X509 V3 certificate extension configuration format, reference https://www.openssl.org/docs/man3.0/man5/x509v3_config.html.