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:
-
get OpenSSL (e.g. link)
unzip it toc:\tools\openssl\
-
open a command prompt (Run as Administrator)
navigate tocd \tools\openssl
as the Certificate Authority
-
set the configuration file environment variable
SET OPENSSL_CONF=.\certs\config\openssl.cnf
-
generate a CA private key (example CA is named Lake House
openssl genrsa -out ./certs/private/lake-house-root-CA.key 4096
-
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
-
(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
-
install the public CA certificate (PEM) on any device that needs to trust the server certificates we're about to create
-
(optional) make a copy of the PEM certificate and change the extension to CRT – Android installs a CRT more easily
as the client organization
- edit the openssl.cnf file:
req_distinguished_name
– edit as desiredalt_names
– update/add/remove as desired
- 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
- (optional) print the details of the request
openssl req -text -noout -in ./certs/requests/klaatu.csr
as the Certificate Authority
- 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
- 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
- import the PFX cert into Windows Certs, Local Machine, Web Hosting (or Personal);
mark the private key as exportable - (optional) right-click on the new cert, Properties, enter a Friendly Name so you can easily identify your new server certificate
- in IIS set the bindings on https to use your new certificate