This article shows how to generate self signed CA, then use it to generate csr and client/server certificate.
We will use openssl to deal with the certs and look at various command line options so we can:
1. generate ca and certs without human intervention, which could be useful during automation
2. validate generated certificate
3. look how to add extensions to the certs
Create CA
Generate CA key
1.1 phrase by default enter manually
openssl genrsa -des3 -out ca.key 4096 Generating RSA private key, 4096 bit long modulus ............................++ ....................++ e is 65537 (0x10001) Enter pass phrase for ca.key: Verifying - Enter pass phrase for ca.key:
1.2 or read from file
openssl genrsa -des3 -passout file:mypass.txt -out ca.key 4096
1.3 or elsewhere
vault read --field=value secret/path_to_ca_key/password | openssl genrsa -des3 -passout stdin -out ca.key 4096 -
2. Check the key
openssl rsa -check -in ca.key -passin pass:mypass -noout RSA key ok
Generate CA cert
2.1 manually enter details
openssl req -new -x509 -days 365 -key ca.key -out ca.crt Enter pass phrase for ca.key: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) []:UK State or Province Name (full name) []: Locality Name (eg, city) []: Organization Name (eg, company) []:Ifrit CA Organizational Unit Name (eg, section) []: Common Name (eg, fully qualified host name) []: Email Address []:
2.2 or via args
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -passin pass:mypass -subj "/C=UK/O=Ifrit Client CA"
2.3 check the cert
openssl x509 -noout -text -in ca.crt Certificate: Data: Version: 1 (0x0) Serial Number: 16882558293151079509 (0xea4ae551eb185c55) Signature Algorithm: sha256WithRSAEncryption Issuer: C=UK, O=Ifrit CA Validity Not Before: Mar 1 22:57:35 2022 GMT Not After : Feb 27 22:57:35 2032 GMT Subject: C=UK, O=Ifrit CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:c1:ea:b5:b4:a6:9c:5f:6b:c4:c8:b1:99:34:72: c8:9c:56:4c:bc:94:54:23:2a:53:26:3b:ad:eb:65:
2.4
with extensions:
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/C=UK/O=Ifrit Client1 CA" -extensions x509_extensions_ca -config ca.conf cat ca.conf [ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] countryName = UK organizationName = Ifrit Client CA [ x509_extensions_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical,CA:true nsComment = "OpenSSL Generated Certificate"
3. generate csr
3.1 manually enter CN details:
openssl req -out 1.csr -new -newkey rsa:2048 -nodes -keyout 1.key -days 365 Generating a 2048 bit RSA private key ................+++ ......................+++ writing new private key to '1.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) []:
3.1 or via ags automatically:
openssl req -out client1.csr -new -newkey rsa:2048 -nodes -keyout client1.key -days 365 -subj "/C=UK/O=Client1/CN=www.client1.com" Generating a 2048 bit RSA private key .........................................................................................+++ ........................+++ writing new private key to 'client1.key' -----
3.2 with conf file:
cat csr.conf [ req ] distinguished_name = req_distinguished_name prompt = no req_extensions = req_ext [ req_distinguished_name ] countryName = UK organizationName = client1 commonName = www.client1.com [ req_ext ] subjectAltName = @alt_names extendedKeyUsage = clientAuth [alt_names] DNS.1 = www.client1.com
(we added few extensions: san and usage)
openssl req -text -noout -verify -in client1.csr verify OK Certificate Request: Data: Version: 0 (0x0) Subject: C=UK, O=client1, CN=www.client1.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:eb:16:d9:99:ff:35:37:ad:84:b2:0d:79:32:49: c3:49:3d:0d:69:76:20:bb:4e:3a:84:3f:2c:aa:39: b6:39:fa:d7:34:af:ea:2c:50:46:ac:e3:3e:e0:f5: 54:e9 Exponent: 65537 (0x10001) Attributes: Requested Extensions: X509v3 Subject Alternative Name: DNS:www.client1.com X509v3 Extended Key Usage: TLS Web Client Authentication openssl req -out client1.csr -new -newkey rsa:2048 -nodes -keyout client1.key -days 365 -config csr.conf
3.1.1 Alternatively create key separately
openssl genrsa -out client1.key 4096 # then csr using the key openssl req -out client1.csr -new -key client1.key -nodes -days 365 -config csr.conf
3.2 validate csr
openssl req -text -noout -verify -in client1.csr verify OK Certificate Request: Data: Version: 0 (0x0) Subject: C=UK, O=Client1, CN=www.client1.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit)
4. gen cert
openssl x509 -req -days 365 -in client1.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client1.crt Signature ok subject=/C=UK/O=client1/CN=www.client1.com Getting CA Private Key Enter pass phrase for ca.key:
4.1
validate
openssl x509 -noout -text -in client1.crt Certificate: Data: Version: 1 (0x0) Serial Number: 1 (0x1) Signature Algorithm: sha1WithRSAEncryption Issuer: C=UK, O=Ifrit CA Validity Not Before: Mar 1 23:58:19 2022 GMT Not After : Mar 1 23:58:19 2023 GMT Subject: C=UK, O=client1, CN=www.client1.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 91:29:f1:6a:82:c6:d9:5b:31:79:7c:94:6d:c2:09: ba:f9:01 Exponent: 65537 (0x10001) Signature Algorithm: sha1WithRSAEncryption 8c:a2:5e:95:12:55:b0:4e:d8:d6:40:6f:e6:df:3b:99:19:4d: 93:eb:06:cb:89:14:0d:11:4f:96:c0:d3:6f:89:7f:92:5c:65: 18:95:69:1c:f3:4e:85:3d:91:d8:db:f5:79:a4:37:fd:22:42: 45:6e:aa:a3:a6:ba:78:07
4.2
cert/key match validation.
keyres=openssl rsa -modulus -noout -in client1.key | openssl md5
fc6b6ed3c084666e99d3988c757f5d51
certres=openssl x509 -modulus -noout -in client1.crt | openssl md5
fc6b6ed3c084666e99d3988c757f5d51
with that in mind our automation could be something like:
[[ "$keyres" == "$certres" ]] || echo "error validating" ...
4.3
where are the extensions?
you need to add them separately again
openssl x509 -req -days 365 -in client1.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client1.crt -extensions req_ext -extfile csr.conf Signature ok subject=/C=UK/O=client1/CN=www.client1.com Getting CA Private Key Enter pass phrase for ca.key: openssl x509 -noout -text -in client1.crt | grep -A 3 Exte X509v3 Extended Key Usage: TLS Web Client Authentication Signature Algorithm: sha1WithRSAEncryption 6e:64:41:df:b7:69:6d:dd:b2:23:8f:1b:c9:cf:80:9c:ea:7d: