Your own Certificate Authority
As mentioned in the previous article, there are some scenarios that it would be useful to run your own Certificate Authority (CA). For example:
- When you require a lot of certificates.
- Authenticate users or client devices.
It is possible to run your own mini Certificate Authority manually.
To request an SSL certificate from a CA like Verisign or GoDaddy, you send them a Certificate Signing Request (CSR), and they give you an SSL certificate in return that they have signed using their root certificate and private key. All browsers have a copy (or access to a copy from the operating system) of the root certificate from the various CAs, so the browser can verify that your certificate was signed by a trusted CA.
That’s why when you generate a self-signed certificate the browser doesn’t trust it. It hasn’t been signed by a CA. The way to get around this is to generate our own root certificate and private key. We then add the root certificate to all the devices we own just once, and then all the certificates we generate will be inherently trusted.
This tutorial uses OpenSSL. OpenSSL is a free and open-source cryptographic library that provides several command-line tools for handling digital certificates. Some of these tools can be used to act as a certificate authority.
Generating root cert
Acting as a certificate authority (CA) means dealing with cryptographic pairs of
private keys and public certificates. The very first cryptographic pair we’ll create
is the root pair. This consists of the root key (ca.key.pem
) and root certificate
(ca.cert.pem
). This pair forms the identity of your CA.
Typically, the root CA does not sign server or client certificates directly. The root CA is only ever used to create one or more intermediate CAs, which are trusted by the root CA to sign certificates on their behalf. This is best practice. It allows the root key to be kept offline and unused as much as possible, as any compromise of the root key is disastrous.
Note
It’s best practice to create the root pair in a secure environment. Ideally, this should be on a fully encrypted, air gapped computer that is permanently isolated from the Internet. Remove the wireless card and fill the ethernet port with glue.
Preparation
Choose a directory (/home/root-ca
) to store all keys and certificates.
# mkdir /home/root-ca
Create the directory structure. The index.txt
and serial
files act as a flat file
database to keep track of signed certificates.
# cd /home/root-ca
# mkdir certs csr crl newcerts private
# chmod 700 private
# touch index.txt
# echo 1000 > serial
You must create a configuration file for OpenSSL to use in /home/root-ca/openssl.cnf
# OpenSSL root CA configuration file.
# Copy to `/home/root-ca/openssl.cnf`.
[ ca ]
# `man ca`
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = /home/root-ca
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/ca.key.pem
certificate = $dir/certs/ca.cert.pem
# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
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.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
# organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
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
# Optionally, specify some defaults.
countryName_default = NL
# stateOrProvinceName_default =
localityName_default = Den Haag
# 0.organizationName_default = Alice Ltd
# organizationalUnitName_default =
emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
The [ ca ]
section is mandatory. Here we tell OpenSSL to use the options from
the [ CA_default ]
section.
The [ CA_default ]
section contains a range of defaults. Make sure you declare the
directory you chose earlier (/home/ca
).
We’ll apply policy_strict
for all root CA signatures, as the root CA is only being
used to create intermediate CAs.
We’ll apply policy_loose
for all intermediate CA signatures, as the intermediate CA is
signing server and client certificates that may come from a variety of third-parties.
Options from the [ req ]
section are applied when creating certificates or certificate
signing requests.
The [ req_distinguished_name ]
section declares the information normally required in a
certificate signing request. You can optionally specify some defaults.
The next few sections are extensions that can be applied when signing certificates.
For example, passing the -extensions v3_ca
command-line argument will apply the options set
in [ v3_ca ]
.
We’ll apply the v3_ca
extension when we create the root certificate.
We’ll apply the v3_ca_intermediate
extension when we create the intermediate
certificate. pathlen:0
ensures that there can be no further certificate authorities
below the intermediate CA.
We’ll apply the usr_cert
extension when signing client certificates, such as those used
for remote user authentication.
We’ll apply the server_cert
extension when signing server certificates, such as those used
for web servers.
Creating the root key
Create the root key (ca.key.pem
) and keep it absolutely secure. Anyone in possession
of the root key can issue trusted certificates. Encrypt the root key with AES 256-bit encryption
and a strong password.
Note
Use 4096 bits for all root and intermediate certificate authority keys. You’ll still be able to sign server and client certificates of a shorter length.
# cd /home/root-ca
# openssl genrsa -aes256 -passout pass:secretpassword -out private/ca.key.pem 4096
# chmod 400 private/ca.key.pem
Creating the root certificate
Use the root key (ca.key.pem
) to create a root certificate (ca.cert.pem
). Give the
root certificate a long expiry date, such as twenty years. Once the root certificate
expires, all certificates signed by the CA become invalid.
Warning
Whenever you use the req tool, you must specify a configuration file to use with the -config option, otherwise OpenSSL will default to /etc/pki/tls/openssl.cnf.
# cd /root/root-ca
# openssl req -config openssl.cnf \
-passin pass:secretpassword \
-key private/ca.key.pem \
-new -x509 -days 7300 -sha256 -extensions v3_ca \
-out certs/ca.cert.pem \
-subj "/C=NL/ST=ZH/O=Alice Ltd/CN=Alice Ltd Root CA"
# chmod 444 certs/ca.cert.pem
To verify the root certificate do:
# openssl x509 -noout -text -in certs/ca.cert.pem
The output shows:
- the
Signature Algorithm
used - the dates of certificate
Validity
- the
Public-Key
bit length - the
Issuer
, which is the entity that signed the certificate - the
Subject
, which refers to the certificate itself
The Issuer
and Subject
are identical as the certificate is self-signed.
Note that all root certificates are self-signed.
Issuer: C=NL, ST=ZH, O=Alice Ltd, CN=Alice Ltd Root CA
Validity
Not Before: May 8 22:29:26 2025 GMT
Not After : May 3 22:29:26 2045 GMT
Subject: C=NL, ST=ZH, O=Alice Ltd, CN=Alice Ltd Root CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
The output also shows the X509v3 extensions. We applied the v3_ca
extension, so the options
from [ v3_ca ]
should be reflected in the output.
X509v3 extensions:
X509v3 Subject Key Identifier:
64:2B:BA:1A:12:9F:D2:B6:62:45:1D:EC:07:17:DC:DB:CA:E8:E9:A5
X509v3 Authority Key Identifier:
64:2B:BA:1A:12:9F:D2:B6:62:45:1D:EC:07:17:DC:DB:CA:E8:E9:A5
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
Minimalistic Root certificate
Alternatively you can take the minimalistic approach:
- Create certificate directory
mkdir ~/ca cd ~/ca
- Generate the private key:
openssl genrsa -des3 -passout pass:secretpassword -out myCA.key 4096
- Generate root certificate:
openssl req -x509 -new -nodes -passin pass:secretpassword -key myCA.key \ -sha256 -days 1825 -out myCA.pem \ -subj "/C=NL/ST=ZH/O=Alice Ltd/CN=Alice Ltd Root CA"
- Verify certificate:
openssl x509 -noout -text -in myCA.pem
You can skip the intermediat certificate steps.
Create intermediate cert
An intermediate certificate authority (CA) is an entity that can sign certificates on behalf of the root CA. The root CA signs the intermediate certificate, forming a chain of trust.
The purpose of using an intermediate CA is primarily for security. The root key can be kept offline and used as infrequently as possible. If the intermediate key is compromised, the root CA can revoke the intermediate certificate and create a new intermediate cryptographic pair.
Prepare the directory
The root CA files are kept in /home/root-ca
. Choose a different directory (/home/int-ca
)
to store the intermediate CA files.
# mkdir /home/int-ca
Create the same directory structure used for the root CA files. It’s convenient to
also create a csr
directory to hold certificate signing requests.
# cd /home/int-ca
# mkdir certs crl csr newcerts private
# chmod 700 private
# touch index.txt
# echo 1000 > serial
Add a crlnumber
file to the intermediate CA directory tree. crlnumber
is used to
keep track of certificate revocation lists.
# echo 1000 > crlnumber
Create a file in /home/int-ca/openssl.cnf
:
# OpenSSL intermediate CA configuration file.
# Copy to `/home/int-ca/openssl.cnf`.
[ ca ]
# `man ca`
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = /home/int-ca
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/intermediate.key.pem
certificate = $dir/certs/intermediate.cert.pem
# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/intermediate.crl.pem
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_loose
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
# organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
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
# Optionally, specify some defaults.
countryName_default = NL
# stateOrProvinceName_default =
localityName_default = Den Haag
# 0.organizationName_default = Alice Ltd
# organizationalUnitName_default =
emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
Five options have changed compared to the root CA configuration file:
[ CA_default ]
dir = /home/int-ca
private_key = $dir/private/intermediate.key.pem
certificate = $dir/certs/intermediate.cert.pem
crl = $dir/crl/intermediate.crl.pem
policy = policy_loose
Create the intermediate key
Create the intermediate key (intermediate.key.pem
). Encrypt the intermediate key with
AES 256-bit encryption and a strong password.
This is done in the intermediate CA
# cd /home/int-ca
# openssl genrsa -aes256 \
-passout pass:secretpassword \
-out private/intermediate.key.pem 4096
# chmod 400 private/intermediate.key.pem
Create the intermediate certificate
Use the intermediate key to create a certificate signing request (CSR). The details should generally match the root CA. The Common Name, however, must be different.
Warning
Make sure you specify the intermediate CA configuration file (
/home/int-ca/openssl.cnf
).
# cd /home/int-ca
# openssl req -config openssl.cnf -new -sha256 \
-passin pass:secretpassword \
-key private/intermediate.key.pem \
-out csr/intermediate.csr.pem \
-subj "/C=NL/ST=ZH/O=Alice Ltd/CN=Alice Ltd Intermediate CA"
To create an intermediate certificate, use the root CA with the v3_intermediate_ca
extension to sign the intermediate CSR. The intermediate certificate should be valid
for a shorter period than the root certificate. Ten years would be reasonable.
Copy the intermeida certificates csr
to the root CA. If you follow
hard security practices you may need to manually copy the csr
file to
the air-gapped root CA system. In our example, we simply copy:
# cp -av /home/int-ca/csr/intermediate.csr.pem /home/root-ca/csr
Warning
This time, specify the root CA configuration file (
/home/root-ca/openssl.cnf
).
# cd /home/root-ca
# openssl ca -config openssl.cnf -extensions v3_intermediate_ca \
-days 3650 -notext -md sha256 \
-passin pass:secretpassword \
-in csr/intermediate.csr.pem \
-out certs/intermediate.cert.pem
Sign the certificate? [y/n]: y
1 out of 1 certificate requests certified, commit? [y/n]y
# chmod 444 certs/intermediate.cert.pem
The index.txt
file is where the OpenSSL ca
tool stores the certificate
database. Do not delete or edit this file by hand. It should now contain a line
that refers to the intermediate certificate.
V 350506223334Z 1000 unknown /C=NL/ST=ZH/O=Alice Ltd/CN=Alice Ltd Intermediate CA
Verify the intermediate certificate
As we did for the root certificate, check that the details of the intermediate certificate are correct.
# openssl x509 -noout -text \
-in certs/intermediate.cert.pem
Verify the intermediate certificate against the root certificate. An OK indicates that the chain of trust is intact.
# openssl verify -CAfile certs/ca.cert.pem \
certs/intermediate.cert.pem
intermediate.cert.pem: OK
Create the certificate chain file
When an application (eg, a web browser) tries to verify a certificate signed by the intermediate CA, it must also verify the intermediate certificate against the root certificate. To complete the chain of trust, create a CA certificate chain to present to the application.
To create the CA certificate chain, concatenate the intermediate and root certificates together. We will use this file later to verify certificates signed by the intermediate CA.
# cat certs/intermediate.cert.pem \
certs/ca.cert.pem > certs/intermediate-full-chain.cert.pem
# chmod 444 certs/intermediate-full-chain.cert.pem
Note
Our certificate chain file must include the root certificate because no client application knows about it yet. A better option, particularly if you’re administrating an intranet, is to install your root certificate on every client that needs to connect. In that case, the chain file need only contain your intermediate certificate.
At this point you need to copy from the root CA to the intermediate CA the files:
- certs/intermediate.cert.pem
- certs/intermediate-full-chain.cert.pem
cp -av /home/root-ca/certs/intermediate*.pem /home/int-ca/certs
Minimalistic Approach
For the minimalistic approach, this entire section can be skipped.
Signing client/server certificates
We will be signing certificates using our intermediate CA. You can use these signed certificates in a variety of situations, such as to secure connections to a web server or to authenticate clients connecting to a service.
Note
The steps below are from your perspective as the certificate authority. A third-party, however, can instead create their own private key and certificate signing request (CSR) without revealing their private key to you. They give you their CSR, and you give back a signed certificate. In that scenario, skip the genrsa and req commands.
Create a key
Our root and intermediate pairs are 4096 bits. Server and client certificates normally expire after one year, so we can safely use 2048 bits instead.
Note
Although 4096 bits is slightly more secure than 2048 bits, it slows down TLS handshakes and significantly increases processor load during handshakes. For this reason, most websites use 2048-bit pairs.
If you’re creating a cryptographic pair for use with a web server (eg, Apache), you probably want to create a key without a password so that you don't need to enter the password every time you restart the web server:
# cd /home/int-ca
# openssl genrsa \
-out private/www.example.com.key.pem 2048
# chmod 400 private/www.example.com.key.pem
On the other hand, if you are creating a key for an interactive user, creating a key with password would be beneficial:
# cd /home/int-ca
# openssl genrsa \
-aes256 \
-passout pass:secretpassword \
-out private/user.alice.key.pem 2048
# chmod 400 private/user.alice.key.pem
Create a certificate
Use the private key to create a certificate signing request (CSR). The CSR details don’t
need to match the intermediate CA. For server certificates, the Common Name must be a
fully qualified domain name (eg, www.example.com
), whereas for client certificates it can
be any unique identifier (eg, an e-mail address). Note that the Common Name cannot be the
same as either your root or intermediate certificate.
# cd /home/int-ca
# openssl req -config openssl.cnf \
-key private/www.example.com.key.pem \
-new -sha256 -out csr/www.example.com.csr.pem \
-subj "/C=NL/CN=www.example.com"
For the user case you may use:
# cd /home/int-ca
# openssl req -config openssl.cnf \
-passin pass:secretpassword \
-key private/user.alice.key.pem \
-new -sha256 -out csr/user.alice.csr.pem \
-subj "/C=NL/CN=user.alice/[email protected]"
To create a certificate, use the intermediate CA to sign the CSR. If the certificate is
going to be used on a server, use the server_cert
extension. If the certificate is going to be
used for user authentication, use the usr_cert
extension. Certificates are usually given a
validity of one year, though a CA will typically give a few days extra for convenience.
# cd /home/int-ca
# openssl ca -config openssl.cnf \
-passin pass:secretpassword \
-extensions server_cert -days 375 -notext -md sha256 \
-in csr/www.example.com.csr.pem \
-out certs/www.example.com.cert.pem
# chmod 444 certs/www.example.com.cert.pem
The intermediate/index.txt file should contain a line referring to this new certificate.
V 350506223334Z 1000 unknown /C=NL/ST=ZH/O=Alice Ltd/CN=Alice Ltd Intermediate CA
For the user case you may use:
# cd /home/int-ca
# openssl ca -config openssl.cnf \
-passin pass:secretpassword \
-extensions usr_cert -days 375 -notext -md sha256 \
-in csr/user.alice.csr.pem \
-out certs/user.alice.cert.pem
# chmod 444 certs/user.alice.cert.pem
Verify the certificate
# openssl x509 -noout -text \
-in certs/www.example.com.cert.pem
The Issuer
is the intermediate CA. The Subject
refers to the certificate itself.
Issuer: C=NL, ST=ZH, O=Alice Ltd, CN=Alice Ltd Intermediate CA
Validity
Not Before: May 8 23:42:47 2025 GMT
Not After : May 18 23:42:47 2026 GMT
Subject: C=NL, CN=www.example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
The output will also show the X509v3
extensions. When creating the certificate, you used
either the server_cert
or usr_cert
extension. The options from the corresponding configuration section will be reflected in the output.
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Server
Netscape Comment:
OpenSSL Generated Server Certificate
X509v3 Subject Key Identifier:
FA:B9:39:0C:09:67:53:20:D1:FC:2D:B9:00:05:91:98:4E:4D:B4:F0
X509v3 Authority Key Identifier:
keyid:D9:13:85:BC:23:8A:24:BA:A0:D9:A2:21:C9:79:95:34:E3:85:E1:2A
DirName:/C=NL/ST=ZH/O=Alice Ltd/CN=Alice Ltd Root CA
serial:10:00
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
Use the CA certificate chain file we created earlier (ca-chain.cert.pem
) to verify that the
new certificate has a valid chain of trust.
# openssl verify -CAfile certs/intermediate-full-chain.cert.pem \
certs/www.example.com.cert.pem
www.example.com.cert.pem: OK
Deploy the certificate
You can now either deploy your new certificate to a server, or distribute the certificate to a client. When deploying to a server application (eg, Apache), you need to make the following files available:
intermediate-full-chain.cert.pem
www.example.com.key.pem
www.example.com.cert.pem
If you’re signing a CSR from a third-party, you don’t have access to their private key
so you only need to give them back the chain file (ca-chain.cert.pem
) and the
certificate (www.example.com.cert.pem
).
Minimal approach
- Create private key:
openssl genrsa -out www.example.com.key 2048
- Generate CSR:
openssl req -new \ -key www.example.com.key \ -out www.example.com.csr \ -addext "subjectAltName = DNS:foo.co.uk, DNS:*.app.example.com" \ -subj "/C=NL/CN=www.example.com"
- Create the certificate: using our CSR, the CA private key and the CA certificate:
openssl x509 -req \ -passin pass:secretpassword \ -CA myCA.pem -CAkey myCA.key -CAcreateserial \ -days 825 -sha256 \ -copy_extensions copyall \ -in www.example.com.csr \ -out www.example.com.crt
We now have three files: www.example.com.key
(the private key), www.example.com.csr
(the
certificate signing request, or csr file), and www.example.com.crt
(the signed certificate).
We can configure local web servers to use HTTPS with the private key and the signed certificate.
Conclusion
This articles covers two approaches for running Certificate Authorities only
using openssl
commands.
The full approach can be implementely quite securely and explicitly support server and client certificates.
The minimal approach is quite straight forward for a quick and dirty solution.