You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
blog/content/posts/create-your-own-ca-cert.md

3.0 KiB

title description date tags draft
Creating and Using a CA Certificate 2023-01-27
SSL
false

Even though there are plenty of free SSL certificate options, you may need to manage your own SSL certs for various reasons.

Below is how to create a CA certificate and issue certs signed with it, as well as some validation steps to make sure you did everything right.

All examples here use the openssl cli tool.

Creating the Certificate Authority's Certificate and Keys

  1. Generate a private key for the CA:
$ openssl genrsa 4096 > ca-key.pem
  1. Generate the X509 certificate for the CA:
    $ openssl req -new -x509 -nodes -days 3650 -sha256 \
	   -subj "/C=US/ST=CO/O=My Org, Inc./OU=Engineering/CN=ca.example.internal" \
       -key ca-key.pem \
       -out ca-cert.pem

Creating the Server's Certificate and Keys

  1. Generate the private key and certificate request:
$ openssl req -newkey rsa:4096 -nodes -days 3650 -sha256 \ # -newkey if you need a new private key
	-subj "/CN=mysite.example.internal" \ # exclude this and you will get interactive prompts
	-keyout server-key.pem \
	-out server-req.pem

# if you already have a private key
$ openssl req -new -nodes -days 3650 -sha256 \
	-subj "/CN=mysite.example.internal" \
	-key server-key.pem \
	-out server-req.pem

# if you want to add SANs
$ openssl req -new -nodes -days 3650 -sha256 \
	-subj "/CN=mydomain.com" \
	-reqexts SAN \
	-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:test.example.internal,DNS:www.example.internal")) \ # to add SANs
	-key server-key.pem \
	-out server-req.pem
  1. Generate the X509 certificate for the server:

-days expiration can be no longer than 398 days (13 months) (thanks Apple) https://www.globalsign.com/en/blog/maximum-ssltls-certificate-validity-now-one-year -set_serial is like an ID number for each cert. It must be a positive integer and unique to each cert signed by the CA. date +%s prints the current number of seconds since the Epoch (00:00:00 UTC, January 1, 1970). See RFC 5280 for details

$ openssl x509 -req -days 398 -set_serial $(date +%s) -sha256 \
   -in server-req.pem \
   -out server-cert.pem \
   -CA ca-cert.pem \
   -CAkey ca-key.pem

# if you want to add SANs
$ openssl x509 -req -days 398 -set_serial $(date +%s) -sha256 \
	-extfile <(printf "subjectAltName=DNS:my.domain.com") \
	-in server-req.pem \
	-out server-cert.pem \
	-CA ca-cert.pem \
	-CAkey ca-key.pem

Verifying the Certificates

  1. Verify the server certificate:
    $ openssl verify -CAfile ca-cert.pem \
       ca-cert.pem \
       server-cert.pem
  1. Verify the client certificate:
    $ openssl verify -CAfile ca-cert.pem \
       ca-cert.pem \
       client-cert.pem

Verify the certificate's content

openssl x509 -in mydomain.com.crt -text -noout