Certificates for development and testing – Part 2 (HOWTO) - arcdev/engram404 GitHub Wiki

originally posted 2016-07-13 at https://engram404.net/certificates-for-development-and-testing-part-2-howto/

Feel free to skip to the Summary at the end.

If you'd like to start with directory template and config file, you can download it from certs and unzip it to c:\tools\openssl\certs\. (It also contains a web.config for IIS to serve PEM files; plus a README.txt with a similar summary to what's below.)

 

Detailed Steps

If you want the background, check out Part 1.

I assume you're here because you want the steps to create your own certificates (for non-production use).

We're going to use an open-source tool called OpenSSL.
I'm too lazy to build the binaries myself, so I picked mine from https://indy.fulgan.com/SSL/. At the time, the latest version was 1.0.2h so that's what I used. (direct 64-bit Windows link)

I'll be using the following:

CA (Certificate Authority)
    Lake House
Server name
    klaatu
Alternate server name
    barada
Main domain
    engram404.net
Alternate server + domain
    nikto.arcticdev.com
Alternate server name
    localhost
IP Address #1
    192.168.1.198
IP Address #2
    127.0.0.1
password
    test1234

I'm assuming you can unzip the archive. I put mine at c:\tools\openssl so all of my paths will be based on that.
Open a command prompt (best to Run as Administrator) and navigate to that directory (cd c:\tools\openssl)

OpenSSL stores a lot of information in a configuration file. You can either specify the configuration file on the command-line for each command, or we can simply set an environment variable. We'll do the latter.
SET OPENSSL_CONF=.\certs\config\openssl.cnf

c:\tools\openssl>SET OPENSSL_CONF=.\certs\config\openssl.cnf

Now, we're going to pretend to be the CA (Certificate Authority).

(This step really only needs to be done once – no matter how many server authentication certificates you create later.)

  • Generate a private key (I'm calling my CA ‘Lake House' just for grins.)

openssl genrsa -out ./certs/private/lake-house-root-CA.key 4096

C:\tools\openssl>openssl genrsa -out ./certs/private/lake-house-root-CA.key 4096
Generating RSA private key, 4096 bit long modulus
..........++
............................................................................................................++
e is 65537 (0x10001)

*   Generate a certificate using that private key (this is what we'll ‘trust' on the various devices)

openssl req -x509 -new -nodes -key ./certs/private/lake-house-root-CA.key -days 3650 -out ./certs/ca/lake-house-root-CA.pem

C:\tools\openssl>openssl req -x509 -new -nodes -key ./certs/private/lake-house-root-CA.key -days 3650 -out ./certs/ca/lake-house-root-CA.pem
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) [US]:
State or Province Name (full name) [Ohio]:
Locality Name (eg, city) [Columbus]:
Organization Name (eg, company) [Lake House]:
Organizational Unit Name (eg, section) [IT]:
Common Name (e.g. for CA enter a company name like Lake House; for request enter a server name) []:Lake House CA

You'll be asked for a bunch questions, just answer them with whatever makes sense. (These don't really matter much.)
I do, however, recommend that the Common Name end in ‘CA'. This will be easier to keep track of which certificate is which later on.

  • _(optional)_Combine the CA private and public keys

(this isn't really necessary, but give you a nice way to combine them and store them in the Windows Certificate store, if you like)
openssl pkcs12 -export -out ./certs/ca/lake-house-root-CA-combined.pfx -inkey ./certs/private/lake-house-root-CA.key -in ./certs/ca/lake-house-root-CA.pem -passin pass:test1234 -passout pass:test1234

c:\tools\openssl>openssl pkcs12 -export -out ./certs/ca/lake-house-root-CA-combined.pfx -inkey ./certs/private/lake-house-root-CA.key -in ./certs/ca/lake-house-root-CA.pem -passin pass:test1234 -passout pass:test1234

Now that we have a CA public key, we'll want to install that on whatever devices need to trust the servers we have.
For Windows, you'll put that certificate in the Trusted Root Certification Authorities store.
For Android, Settings -> Lock screen and security -> Other security settings -> Install from device storage.
(Note: when installing in Android be sure to confirm that your certificate is now visible. If not, stop here and review. There's no point going any farther – assuming you need an Android device to trust you.)
(Tip: copying the PEM certificate and changing the extension to CRT makes it easier to install on Android. Keep a PEM copy around for our later steps, though.)

Ok, we've got our CA all setup, so let's pretend to be a client who needs to request a certificate in order to be able to authenticate their server to its users.

We're going to create a Certificate Signing Request (CSR) – for each server we want to authenticate.

  • open up the openssl.cnf

  • (optional) look for the req_distinguished_name section (around line 125) and edit the defaults according to your choices

  • look for the alt_names section (at the end of the file) and update the DNS names and IP addresses
    See this for more detail, but the short version is this: each name your server is known by should be listed here. You can authenticate an entire domain with a wildcard (e.g. *.engram404.net). You can list as many IP addresses (either v4 or v6) as you like, though IP does not support wildcards.

Back to the command prompt…

  • generate a private key and CSR for our server named ‘kaatu' (which in my example is known by other names as well- see the config.cnf file alt_names

openssl req -new -out ./certs/requests/klaatu.csr -keyout ./certs/private/klaatu.key -newkey rsa:4096 -passout pass:test1234

C:\tools\openssl>openssl req -new -out ./certs/requests/klaatu.csr -keyout ./certs/private/klaatu.key -newkey rsa:4096 -passout pass:test1234
Generating a 4096 bit RSA private key
....................................................................................................++
........................++
writing new private key to './certs/private/klaatu.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) [US]:
State or Province Name (full name) [Ohio]:
Locality Name (eg, city) [Columbus]:
Organization Name (eg, company) [Lake House]:
Organizational Unit Name (eg, section) [IT]:
Common Name (e.g. for CA enter a company name like Lake House; for request enter a server name) []:klaatu

(Note: if you were a real organization requesting certificates, you might choose to generate a single private key for the organization and individual CSRs for the each server. We'll just combine the two since there's no harm either way.)

  • (optional) print out the details of the request – especially, if you want to see all of the subjectAltName entries

openssl req -text -noout -in ./certs/requests/klaatu.csr

C:\tools\openssl>openssl req -text -noout -in ./certs/requests/klaatu.csr
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=US, ST=Ohio, L=Columbus, O=Lake House, OU=IT, CN=klaatu
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:bd:bf:84:80:78:c1:57:e9:59:ed:35:a2:b0:21:
                    ed:21:61:38:e3:a5:69:7d:90:23:80:f4:72:e8:c4:
                    f5:37:ef:9c:a6:44:39:a8:0c:3c:b8:8a:61:f9:f9:
                    ea:84:a7:a0:42:db:28:de:f7:07:9e:34:2d:3f:33:
                    34:42:85:0b:26:4f:39:9c:42:dd:ed:13:af:8c:31:
                    aa:36:ba:18:c8:7a:08:ed:8f:d8:12:56:f0:1f:c9:
                    55:25:47:d2:73:f5:cc:3d:da:3e:35:23:63:ab:b9:
                    e0:41:36:34:13:80:8c:6b:e0:fe:40:88:61:29:a6:
                    c0:b5:06:c8:5a:a1:04:f0:45:e6:b4:b0:99:dd:82:
                    df:9e:a5:f6:77:18:fd:b3:43:c4:0e:08:39:6b:6e:
                    65:5b:79:50:32:de:27:c5:50:97:ab:5c:bf:35:4d:
                    0c:f0:85:90:7c:73:1f:05:57:ef:77:2d:35:45:2d:
                    1a:3a:81:8e:12:9b:c9:ba:d9:73:c6:59:bf:9f:f5:
                    dc:22:f6:26:36:69:27:a6:01:cb:41:de:44:dc:bf:
                    d0:53:3b:63:59:be:54:d3:0a:3a:c2:cb:23:95:9b:
                    9f:cd:ce:57:62:25:38:bf:50:7d:8f:ca:5f:3b:9d:
                    c6:53:7a:d4:b5:25:dc:c0:d2:af:59:be:1c:c8:53:
                    07:b0:a6:72:63:02:9b:ef:80:42:86:5b:fe:f5:af:
                    e1:3e:b1:95:71:d1:25:92:28:af:0a:85:8c:20:1a:
                    86:78:47:09:eb:bc:f0:5d:64:c0:11:08:34:61:7b:
                    42:04:22:e4:9b:ec:59:3a:a9:ec:85:79:f9:69:88:
                    ff:c5:d5:72:51:e9:86:c4:68:b4:0c:b1:54:c8:a2:
                    a5:b9:43:3a:4e:07:2d:4a:72:02:3d:f8:05:f2:d3:
                    00:d9:00:3f:6d:4c:a0:35:a9:0d:47:2f:12:08:91:
                    14:4b:85:c7:cc:dc:3d:63:4b:6d:8e:03:0f:0a:ab:
                    eb:71:d2:23:ed:eb:fd:82:60:a5:26:9e:6c:00:ab:
                    1d:fb:82:55:2e:61:0b:86:2e:67:f7:1b:c9:df:4f:
                    c4:ff:a9:ce:f7:d4:2e:d3:e9:ed:95:bd:0e:35:61:
                    25:0b:d3:e5:23:86:9e:ba:19:19:6c:c9:68:5e:80:
                    19:8b:09:f7:51:23:ce:14:e4:99:5b:88:d6:71:f2:
                    a5:95:d1:65:57:52:16:a7:51:e6:d7:b5:b7:b2:14:
                    e0:2c:80:01:cf:a1:12:02:85:d3:c5:a3:a3:41:b0:
                    c1:30:6a:0f:61:75:7c:56:00:04:bc:a9:73:4b:a0:
                    ee:ce:d7:08:21:8a:34:3e:d6:60:df:db:ac:58:b3:
                    0e:4d:33
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:klaatu, DNS:barada, DNS:nikto.arcticdev.com, DNS:*.engram404.net, DNS:localhost, IP Address:192.168.1.198, IP Address:127.0.0.1
    Signature Algorithm: sha256WithRSAEncryption
         5b:5d:0d:75:3f:ff:5c:df:fc:6c:f5:31:ab:82:68:d8:37:d1:
         e4:f8:5b:3d:47:b9:10:5f:22:f0:3e:1c:2d:fa:83:e7:50:ee:
         5f:e3:da:71:9a:d1:50:7f:5a:29:4d:0f:0a:fc:df:3a:18:4d:
         dc:2b:6d:c9:92:8e:f2:53:07:fb:1e:7b:02:fe:09:8c:48:3a:
         2b:95:d0:e9:35:f9:83:e8:06:5b:ea:3c:4f:25:72:64:3a:ff:
         a7:cf:3a:5e:7c:d8:9b:f0:4d:76:40:05:5e:7f:e5:ec:88:06:
         db:8c:cf:05:36:45:38:70:02:6e:31:94:25:8d:f6:26:bc:10:
         d1:5f:90:8a:56:17:14:30:0a:e8:16:36:a7:7a:7a:77:46:ac:
         06:da:96:e9:20:eb:b7:05:9f:a5:07:ab:2f:42:7c:83:54:0a:
         a5:3e:77:4a:ad:6d:95:2a:0c:ce:17:85:40:32:e2:b7:c1:14:
         f5:a9:a2:f8:29:ea:a3:ca:ea:d7:b1:58:0d:41:76:64:a4:83:
         49:b1:4b:c0:e8:82:9a:a4:95:18:93:c0:e3:25:74:05:27:81:
         dc:57:6a:c1:76:b5:a0:08:47:d1:7b:78:53:e2:f1:c4:97:26:
         14:55:90:13:fe:28:dc:a2:ab:59:a8:62:ff:c0:1e:4c:6a:f2:
         48:28:f1:3d:a6:6a:57:9c:34:db:71:17:89:93:22:1e:f5:75:
         5b:77:6a:a4:0a:98:54:c0:fe:a7:a9:0f:eb:59:99:1b:60:85:
         7a:0e:97:f6:12:d1:54:6f:79:46:26:b7:8c:3a:93:45:d4:17:
         fb:3b:c3:f5:35:cd:8f:f9:23:32:a1:32:64:06:b1:ba:bf:07:
         ea:22:aa:ed:e1:a0:de:b7:28:4b:5b:29:7c:75:5b:89:92:ae:
         43:2e:f0:79:01:25:01:c6:5d:7f:e1:2f:36:fa:c6:44:46:e1:
         f8:79:a1:76:f0:93:ea:d4:95:ee:c6:55:07:15:77:aa:ae:71:
         6d:c2:fe:d9:5e:fa:2e:ae:5f:f9:67:1c:01:5b:62:b5:49:94:
         4c:1b:1c:02:0d:21:eb:58:cb:ed:cd:4c:f4:bf:1d:2a:76:73:
         76:07:8d:f7:e1:7d:ee:32:e0:3b:07:33:d2:12:fd:f9:df:c1:
         f3:d9:3a:26:35:4d:dd:2c:6b:04:9f:ce:9f:b4:39:d5:62:03:
         8f:bb:5e:82:1d:06:f1:aa:e1:03:4f:bc:30:66:0f:ac:ca:f0:
         15:7b:55:4b:7c:4d:6a:2f:90:0b:4e:1e:4d:85:11:40:aa:f8:
         69:a5:1e:0d:6d:bb:d1:6a:7d:04:3b:21:9a:53:be:b9:6a:93:
         bf:a4:1b:4c:5a:1d:4a:68

In the real world, we'd send this CSR off to a CA to sign for us.

In our case, we are the CA, so let's go back to pretending to be the CA.

  • sign the CSR with our CA cert & private key

openssl ca -cert ./certs/ca/lake-house-root-CA.pem -keyfile ./certs/private/lake-house-root-CA.key -in ./certs/requests/klaatu.csr -out ./certs/newcerts/klaatu.crt -batch -create_serial

C:\tools\openssl>openssl ca -cert ./certs/ca/lake-house-root-CA.pem -keyfile ./certs/private/lake-house-root-CA.key -in ./certs/requests/klaatu.csr -out ./certs/newcerts/klaatu.crt -batch -create_serial
Using configuration from .\certs\config\openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            ee:2f:f3:ef:9b:fa:f9:10
        Validity
            Not Before: Jul 13 13:45:29 2016 GMT
            Not After : Jul 10 13:45:29 2026 GMT
        Subject:
            countryName               = US
            stateOrProvinceName       = Ohio
            organizationName          = Lake House
            organizationalUnitName    = IT
            commonName                = klaatu
        X509v3 extensions:
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                96:D1:73:8A:46:61:73:6A:68:12:08:60:AB:21:64:1A:28:A3:07:7A
            X509v3 Authority Key Identifier:
                keyid:77:F4:E9:58:D1:EA:F1:D8:2C:B9:B3:32:1B:61:38:68:D5:AE:0F:3A

            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:klaatu, DNS:barada, DNS:nikto.kaelish.org, DNS:*.lakehouse.com, DNS:localhost, IP Address:192.168.1.198, IP Address:127.0.0.1
Certificate is to be certified until Jul 10 13:45:29 2026 GMT (3649 days)

Write out database with 1 new entries
Data Base Updated

(back at the client)

  • combine the organization/server private key with the signed certificate – for Windows and IIS

openssl pkcs12 -export -out ./certs/newcerts/klaatu-pk.pfx -inkey ./certs/private/klaatu.key -in ./certs/newcerts/klaatu.crt -passin pass:test1234 -passout pass:test1234

C:\tools\openssl>openssl pkcs12 -export -out ./certs/newcerts/klaatu-pk.pfx -inkey ./certs/private/klaatu.key -in ./certs/newcerts/klaatu.crt -passin pass:test1234 -passout pass:test1234

Import the PFX certificate into the Windows Certificate Store in Web Hosting (or Personal, if you're using a version of Windows/IIS without the Web Hosting store). I recommend marking the private key as exportable.
(Note: do not import the CRT file as it doesn't have a private key and won't work.
(optional) Right-click on the new certificate (in the Windows Certificate Store), choose Properties, and enter a Friendly Name so you can easily identify your certificate.

Finally, configure IIS to use the certificate.

 

Summary

Let's summarize all of that:

  1. get OpenSSL (e.g. link)
    unzip it to c:\tools\openssl\

  2. open a command prompt (Run as Administrator)
    navigate to

    cd \tools\openssl

as the Certificate Authority

  1. set the configuration file environment variable

    SET OPENSSL_CONF=.\certs\config\openssl.cnf

  2. generate a CA private key (example CA is named Lake House

    openssl genrsa -out ./certs/private/lake-house-root-CA.key 4096

  3. generate a CA (public)certificate

    openssl req -x509 -new -nodes -key ./certs/private/lake-house-root-CA.key -days 3650 -out ./certs/ca/lake-house-root-CA.pem

  4. (optional) combine the CA private key & public certificate for Windows

    openssl pkcs12 -export -out ./certs/ca/lake-house-root-CA-combined.pfx -inkey ./certs/private/lake-house-root-CA.key -in ./certs/ca/lake-house-root-CA.pem -passin pass:test1234 -passout pass:test1234

  5. install the public CA certificate (PEM) on any device that needs to trust the server certificates we're about to create

  6. (optional) make a copy of the PEM certificate and change the extension to CRT – Android installs a CRT more easily

as the client organization

  1. edit the openssl.cnf file:
  • req_distinguished_name – edit as desired
  • alt_names – update/add/remove as desired
  1. generate a private key and certificate signing request (CSR) for the server (example server name is klaatu)

`openssl req -new -out ./certs/requests/klaatu.csr -keyout ./certs/private/klaatu.key -newkey rsa:4096 -passout pass:test1234

  1. (optional) print the details of the request

openssl req -text -noout -in ./certs/requests/klaatu.csr

as the Certificate Authority

  1. sign the CSR with the CA private key (produces 2 copies of the output certificate)

openssl ca -cert ./certs/ca/lake-house-root-CA.pem -keyfile ./certs/private/lake-house-root-CA.key -in ./certs/requests/klaatu.csr -out ./certs/newcerts/klaatu.crt -batch -create_serial

as the client organization

  1. generate a combined certificate + client private key (to a PFX file) for IIS

openssl pkcs12 -export -out ./certs/newcerts/klaatu-pk.pfx -inkey ./certs/private/klaatu.key -in ./certs/newcerts/klaatu.crt -passin pass:test1234 -passout pass:test1234

  1. import the PFX cert into Windows Certs, Local Machine, Web Hosting (or Personal);
    mark the private key as exportable
  2. (optional) right-click on the new cert, Properties, enter a Friendly Name so you can easily identify your new server certificate
  3. in IIS set the bindings on https to use your new certificate