Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save anandkkpr/851e57c3aa43e1e36df164f1c215609e to your computer and use it in GitHub Desktop.
Save anandkkpr/851e57c3aa43e1e36df164f1c215609e to your computer and use it in GitHub Desktop.
Self Signed Certificate with Custom Root CA for use with DNS/Domain Names AND IP addresses for Local Development

Additional references

Create Root CA (Done once)

Create Root Key

Attention: this is the key used to sign the certificate requests, anyone holding this can sign certificates on your behalf. So keep it in a safe place!

openssl genrsa -des3 -out rootCA.key 4096

If you want a non password protected key just remove the -des3 option

Create and self sign the Root Certificate

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

Here we used our root key to create the root certificate that needs to be distributed in all the computers that have to trust us.

Create a certificate (Done for each server)

This procedure needs to be followed for each server/appliance that needs a trusted certificate from our CA

Create the Certificate Key file

openssl genrsa -out mydomain.com.key 2048

Create the Certificate Signing Request File (csr)

The certificate signing request is where you specify the details for the certificate you want to generate. This request will be processed by the owner of the Root key (you in this case since you create it earlier) to generate the certificate.

Important: You will need to create a supporting openssl configuration file that will be used for BOTH creating the Certificate Request (the *.csr file) and the Certificate (the *.crt file).

Create the Certificate Configuration File

Doing this will provide the details necessary for openssl to fill the "Subject Alternative Name" section in the certificate created. New web browsers use this section to identify which Domain Names (aka DNS.* entries) and which IP Addresses (aka IP.* entries) are valid for the certificate.

certificate.conf

[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[dn]
C = CA
ST = Ontario
L = Toronto
O = CompanyName Inc.
OU = Org. Unit Name (e.g. Software Engineering)
emailAddress = domain-admin@companynameinc.com
CN = Common Name (e.g. Local Test Devices)

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = testing.companynameinc.com
DNS.2 = staging.companynameinc.com
IP.1 = 192.168.123.101
IP.2 = 192.168.123.102

Generate the Signed Certificate using the "certificate.conf" file

We pass the certificate.conf file to the Certificate Request which provides all info needed by OpenSSL to make the *.csr file.

openssl req -new -key mydomain.com.key -out mydomain.com.csr -config certificate.conf

Verify the csr's content

openssl req -noout -text -in mydomain.com.csr

Generate the final Certificate (crt) using the mydomain csr and key signed by the CA Root key

openssl x509 -req -in mydomain.com.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out mydomain.com.crt -days 500 -sha256 -extfile certificate.conf -extensions req_ext

Verify the certificate's content

openssl x509 -text -noout -in mydomain.com.crt

What's Next?

You can now use mydomain.com.key and mydomain.com.crt files to serve your local test applications. If you are trying to test your apps on devices (like Android tablets) and, you're testing a Web App (as I am), you'll need to manually import both the Root and Mydomain Certificates to your device. By installing both your certificates manually, directly into your device, you will be able to test your Web App in "Chromeless" mode without Google Chrome warning you that the SSL certificate is not valid. The reason this may be important (as it is in my case) is that that HTTPS SSL warning bar eats up screen real estate thereby making UI development a guessing game with regards to exactly how your app will look in production mode using authentic SSL certficates and thereby not having this warning bar.

For Android

First, send your root certificate to the devices's Download folder.

adb push rootCA.crt /sdcard/Download

Next, use these instructions to install the certificate:

  • i.e. navigate to Security > Install from SD card locate the rootCA.crt file and click on it, you'll likely be prompted for your password/pin/pattern to continue

For OSX (useful for verifying before installing on Android or other mobile devices)

You need only create a copy of the Root Certificate, changing the extension from crt to cer. You can then locate that file in Finder and double-clicking on it will open you Keychain and import it.

This link provides some info for older version of OSX, for newer versions, double click on the cer file and then:

  • locate the installed certificate
  • double click on it
  • expand the "Trust" section
  • set "Secure Sockets Layer (SSL)" to Always Trust
  • set "X.509 Basic Policy" to Always Trust

NEW For Android 10 and Higher

From: https://stackoverflow.com/a/61355344

Considering this is Android 10 I think this might be the same issue: Install self-signed certificates no longer working in Android Q

openssl pkcs12 -export -in rootCA.crt -inkey rootCA.key -out rootCA.android-10.p12
openssl pkcs12 -export -in mydomain.com.crt -inkey mydomain.com.key -out mydomain.com.android-10.p12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment