User Tools

Site Tools


crypto:x509

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
crypto:x509 [2020-05-19 19:53] – tidying up notes gabrielcrypto:x509 [2020-05-27 16:56] (current) – reformatting page, tutorial is now on GitLab gabriel
Line 1: Line 1:
-====== Creating an intermediate and root certificate authority with OpenSSL ======+====== The Quay Certificate Authority ======
  
 +The current versions of certificates and CRLs can be found here:
  
-I run a small certificate authority to sign x509 certificates for use internally since I have now implemented [[http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security|HSTS]] for the quay.net domain.+  * **CA root:** https://quay.net/pub/ca/root-q2.crt 
 +    * **Root CRL:** https://quay.net/pub/ca/root-q2.crl
  
-This upshot of this change on the public domain means that even to access HTTP resources on my internal subdomain web browsers will refuse to use unencrypted connections or untrusted certs.+  * **Intermediate signing certificate:** https://quay.net/pub/ca/sign-s2.crt 
 +    * **Intermediate CRL:** https://quay.net/pub/ca/sign-q2.crl
  
-This page is a brief overview of how to configure a self-signed CA that implements an intermediate CA in order to allow us to take the root CA offline.+===== General comments =====
  
-===== mkca.sh helper script =====+Generally speaking, [[https://letsencrypt.org/|Let's Encrypt]] is a better solution than using a self-hosted certificate authority in 2020.  For most users this is what I recommend.
  
-Stick this somewhere to help set up the directory structures for the two CAs you are about to create.+Let's Encrypt is stable, easy to configure, and trusted in all major browsers, however its primary drawback is that it can be very awkward to use with domains that are not on the public Internet.  Therefore, I run a certificate authority to sign x509 certificates for use internally as [[http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security|HSTS]] is implemented for the quay.net domain.  This upshot of this configuration on the public domain is that in order to access HTTP resources on my internal subdomain I require trusted TLS certificates.
  
-<code bash> +I'm in the process of deprecating this page and moving the actual configuration to a GitLab project rather than static notes.  In the future this page will only contain specific information related to my local usage.
-#!/bin/bash+
  
-workdir=${1} +The GitLab project can be found here: [[https://gitlab.com/gmobrien/quayCA|The Quay X.509 Certificate Authority]]
-mkdir -p ${workdir}/{certs,crl,csr,newcerts,private} +
-chmod 700 ${workdir}/private +
-touch ${workdir}/certindex +
-echo 1000 > ${workdir}/serialfile +
-</code>+
  
-===== Root CA configuration =====+===== Local usage notes =====
  
-We'll set some environment variables for the root CA in order to simplify changing the name.+Work in progress.
  
-<code bash> 
-export CA=quayrootCA 
-export workdir=${CA} 
-export OPENSSL_CONF=${workdir}/${CA}.conf 
-export privkey=${workdir}/private/privkey.pem 
-export cacert=${workdir}/certs/${CA}.crt 
- 
-mkca.sh $CA 
-</code> 
- 
-==== Root CA OpenSSL configuration file  ==== 
- 
-Place this file in ''$OPENSSL_CONF'' location you set above, this will govern OpenSSL usage for the root CA and can be customized as you see fit.  The settings here are relatively sane. 
- 
-<code> 
-RANDFILE = /dev/arandom 
- 
-[ ca ] 
-default_ca = quayrootCA 
- 
-[ crl_ext ] 
-# issuerAltName=issuer:copy  #this would copy the issuer name to altname 
-issuerAltName = URI:https://quay.net/pub/ca/quayrootCA.crt 
-authorityKeyIdentifier = keyid:always,issuer 
- 
-[ quayrootCA ] 
-new_certs_dir = /home/ca/quayrootCA/certs 
-unique_subject = no 
-certificate = /home/ca/quayrootCA/certs/quayrootCA.crt 
-database = /home/ca/quayrootCA/certindex 
-private_key = /home/ca/quayrootCA/private/privkey.pem 
-serial = /home/ca/quayrootCA/serialfile 
-default_days = 1096 
-default_md = sha256 
-policy = quayrootCA_policy 
-x509_extensions = quayrootCA_extensions 
- 
-[ quayrootCA_policy ] 
-commonName = supplied 
-stateOrProvinceName = supplied 
-countryName = supplied 
-emailAddress = optional 
-organizationName = supplied 
-organizationalUnitName = optional 
- 
-[ quayrootCA_extensions ] 
-basicConstraints = CA:false 
-subjectKeyIdentifier = hash 
-authorityKeyIdentifier = keyid:always,issuer 
-keyUsage = digitalSignature,keyEncipherment 
-extendedKeyUsage = serverAuth 
-crlDistributionPoints = URI:https://quay.net/pub/ca/quayrootCA.crl 
- 
-[ v3_ca ] 
-subjectKeyIdentifier=hash 
-authorityKeyIdentifier=keyid:always,issuer 
-basicConstraints = CA:true 
-keyUsage = cRLSign, keyCertSign 
- 
-[ req ] 
-default_bits = 2048 
-default_keyfile = privkey.pem 
-distinguished_name = req_distinguished_name 
-attributes = req_attributes 
- 
-[ req_distinguished_name ] 
-countryName = Country Name (2 letter code) 
-countryName_default = CA 
-countryName_min = 2 
-countryName_max = 2 
- 
-stateOrProvinceName = State or Province Name (full name) 
-stateOrProvinceName_default = Ontario 
- 
-localityName = Locality Name (eg, city) 
-localityName_default = Toronto 
- 
-0.organizationName = Organization Name (eg, company) 
-0.organizationName_default = The Quay 
- 
-organizationalUnitName = Organizational Unit Name (eg, section) 
- 
-commonName = Common Name (eg, fully qualified host name) 
-commonName_max = 64 
- 
-emailAddress = Email Address 
-emailAddress_default = gabriel@quay.net 
-emailAddress_max = 64 
- 
-[ req_attributes ] 
-#challengePassword = A challenge password 
-#challengePassword_min = 0 
-#challengePassword_max = 20 
-</code> 
- 
-==== Generate root CA ==== 
- 
-<code bash> 
-# generate a key for the CA (you can strip the password by omitting -aes256) 
-openssl genrsa -aes256 -out $privkey 4096 
-chmod 600 $privkey 
- 
-# generate the CA root certificate (you can tweak the keysize and validity duration as you see fit) 
-openssl req -newkey rsa:4096 -x509 \ 
-  -days 3650 \ 
-  -key $privkey \ 
-  -sha256 \ 
-  -extensions v3_ca \ 
-  -out $cacert 
-</code> 
- 
-===== Intermediate CA configuration ===== 
- 
-We're going to craete an intermediate CA (this allows us to keep the root CA offline, just in case). 
- 
-Set the environment for the Intermediate CA. 
- 
-<code bash> 
-export CA=quayintCA 
-export workdir=~/${CA} 
-export OPENSSL_CONF=${workdir}/${CA}.conf 
-export privkey=${workdir}/private/privkey.pem 
-export cacert=${workdir}/certs/${CA}.crt 
-</code> 
- 
-==== Intermediate CA OpenSSL configuration file  ==== 
- 
-Place this file in ''$OPENSSL_CONF'' location you set in the previous section, this will govern OpenSSL usage for the intermediate CA and can be customized as you see fit.  The settings here are relatively sane.  //These will be the settings you use normally to manage server certificates.// 
- 
-<code> 
-RANDFILE = /dev/arandom 
- 
-[ ca ] 
-default_ca = quayintCA 
- 
-[ crl_ext ] 
-# issuerAltName=issuer:copy  #this would copy the issuer name to altname 
-issuerAltName = URI:https://quay.net/pub/ca/quayintCA.crt 
-authorityKeyIdentifier = keyid:always,issuer 
- 
-[ quayintCA ] 
-new_certs_dir = /home/ca/quayintCA/certs 
-unique_subject = no 
-certificate = /home/ca/quayintCA/certs/quayintCA.crt 
-database = /home/ca/quayintCA/certindex 
-private_key = /home/ca/quayintCA/private/privkey.pem 
-serial = /home/ca/quayintCA/serialfile 
-default_days = 1096 
-default_md = sha256 
-policy = quayintCA_policy 
-x509_extensions = quayintCA_extensions 
- 
-[ quayintCA_policy ] 
-commonName = supplied 
-stateOrProvinceName = supplied 
-countryName = supplied 
-emailAddress = optional 
-organizationName = supplied 
-organizationalUnitName = optional 
- 
-[ quayintCA_extensions ] 
-basicConstraints = CA:false 
-subjectKeyIdentifier = hash 
-authorityKeyIdentifier = keyid:always,issuer 
-keyUsage = digitalSignature,keyEncipherment 
-extendedKeyUsage = serverAuth 
-crlDistributionPoints = URI:https://quay.net/pub/ca/quayintCA.crl 
- 
-[ v3_ca ] 
-subjectKeyIdentifier=hash 
-authorityKeyIdentifier=keyid:always,issuer 
-basicConstraints = CA:true 
-keyUsage = cRLSign, keyCertSign 
- 
-[ req ] 
-default_bits = 2048 
-default_keyfile = privkey.pem 
-distinguished_name = req_distinguished_name 
-attributes = req_attributes 
- 
-[ req_distinguished_name ] 
-countryName = Country Name (2 letter code) 
-countryName_default = CA 
-countryName_min = 2 
-countryName_max = 2 
- 
-stateOrProvinceName = State or Province Name (full name) 
-stateOrProvinceName_default = Ontario 
- 
-localityName = Locality Name (eg, city) 
-localityName_default = Toronto 
- 
-0.organizationName = Organization Name (eg, company) 
-0.organizationName_default = The Quay 
- 
-organizationalUnitName = Organizational Unit Name (eg, section) 
- 
-commonName = Common Name (eg, fully qualified host name) 
-commonName_max = 64 
- 
-emailAddress = Email Address 
-emailAddress_default = gabriel@quay.net 
-emailAddress_max = 64 
- 
-[ req_attributes ] 
-#challengePassword = A challenge password 
-#challengePassword_min = 0 
-#challengePassword_max = 20 
-</code> 
- 
-==== Generate a private key for the Intermediate CA ==== 
- 
-<code bash> 
-openssl genrsa -aes256 -out $privkey 4096 
-chmod 600 $privkey 
-</code> 
- 
-==== Generate the intermediate CA certificate signing request ==== 
- 
-<code bash> 
-openssl req -config $OPENSSL_CONF -sha256 -new -key $privkey -out $workdir/csr/$CA.csr 
-</code> 
- 
-==== Sign the intermediate CA ==== 
- 
-We need to switch our environment back to use the root CA. 
- 
-<code bash> 
-export CA=quayrootCA 
-export workdir=${CA} 
-export OPENSSL_CONF=${workdir}/${CA}.conf 
-export privkey=${workdir}/private/privkey.pem 
-export cacert=${workdir}/certs/${CA}.crt 
- 
-openssl ca -keyfile $privkey \ 
-  -cert $cacert \ 
-  -extensions v3_ca \ 
-  -notext -md sha256 \ 
-  -in ${workdir}/csr/quayintCA.csr \ 
-  -out ~/quayintCA/certs/quayintCA.crt \ 
-  -days 4018 
- 
-</code> 
- 
-==== Create the intermediate CA certificate chain ==== 
- 
-We'll need a certificate chain to use with web browsers. 
- 
-<code bash> 
-cat ~/quayintCA/certs/quayintCA.crt \ 
-  ~/quayrootCA/certs/quayrootCA.crt > \ 
-  ~/quayintCA/certs/quaycerts.crt 
-</code> 
- 
-===== Creating server certificates ===== 
- 
-<code bash> 
-export CA=quayintCA 
-export workdir=${CA} 
-export OPENSSL_CONF=${workdir}/${CA}.conf 
-export privkey=${workdir}/private/privkey.pem 
-export cacert=${workdir}/certs/${CA}.crt 
- 
-# create a certificate request and private key for my router 
-export certname=router.in.quay.net 
-openssl req -newkey rsa:2048 -nodes -out ${certname}.csr -keyout ${certname}.key 
- 
-# now sign the certificate request 
-openssl ca -keyfile $privkey \ 
-    -cert $cacert \ 
-    -notext -md sha256 \ 
-    -in ${certname}.csr -out ${certname}.crt 
-</code> 
- 
-===== OpenSSL tips ===== 
- 
-Decode an x509 certificate file to plain text: 
- 
-<code bash> 
-openssl x509 -in certifcate_file.crt -text 
-</code> 
- 
-Verify a certificate is signed by a CA: 
- 
-<code bash> 
-# verify intermediate certificate 
-openssl verify -CAfile ~/quayrootCA/quayrootCA.crt ~/quayintCA/quayintCA.crt 
- 
-# verify server cert using cert chain 
-openssl verify -CAfile ~/quayintCA/quayCAcertchain.crt router.in.quay.net.crt  
-</code> 
-===== Notes ===== 
- 
-I publish the CA root certificate here in the off chance that somebody outside my network might require it: https://quay.net/pub/ca/quayrootCA.crt 
- 
-Here is the CRL: https://quay.net/pub/ca/quayrootCA.crl 
crypto/x509.1589932417.txt.gz · Last modified: 2020-05-19 19:53 by gabriel