Skip to content

How to generate self signed certificates with openssl

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: