Acting as a Certificate Authority with OpenSSL

Damian
Coding Snippets
Published in
6 min readMay 2, 2017

Certificates for websites and web services are easily obtained on the internet through companies like GoDaddy, Comodo and Lets Encrypt but what do you do when you cannot access the internet? or want more control of expiration dates?

This guide provides a way to act as a Certificate Authority (CA) and create certificates signed by your company. It deals with the deprecation of sha1 as well as the new requirements on certificates that were added into Google Chrome build 58 causing the error:

Subject Alternative Name Missing The certificate for this site does not contain a Subject Alternative Name extension containing a domain name or IP address.

Steps 1–4 cover the setup process, step 5 shows how to create a certificate for a specific server and steps 6 & 7 cover how to install and trust the certificate.

1. Getting OpenSSL installed

Visit https://www.openssl.org/ and click the downloads link to get OpenSSL installed. For Windows installations visit https://wiki.openssl.org/index.php/Binaries

For this guide i used the OpenSSL binaries from here. For simplicity i describe all files in the same folder.

2. Configuring OpenSSL

OpenSSL is highly configurable. For this guide please create a file called openssl.cnf and paste the following contents into it:

[ req ]default_bits = 2048default_keyfile = server-key.pemdistinguished_name = subjectreq_extensions = req_extx509_extensions = x509_extstring_mask = utf8only
[ subject ]
countryName = Country Name (2 letter code)countryName_default = USstateOrProvinceName = State or Province Name (full name)stateOrProvinceName_default = NYlocalityName = Locality Name (eg, city)localityName_default = New YorkorganizationName = Organization Name (eg, company)organizationName_default = Example, LLCcommonName = Common Name (e.g. server FQDN or YOUR name)commonName_default = Example CompanyemailAddress = Email AddressemailAddress_default = test@example.com[ x509_ext ]subjectKeyIdentifier = hashauthorityKeyIdentifier = keyid,issuerbasicConstraints = CA:FALSEkeyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEnciphermentsubjectAltName = @alternate_names[ req_ext ]subjectKeyIdentifier = hashbasicConstraints = CA:FALSEkeyUsage = digitalSignature, keyEnciphermentsubjectAltName = @alternate_names[ alternate_names ]DNS.1 =myserverDNS.2 =localhostDNS.2 =localhost.localadminDNS.2 =127.0.0.1

Important: You must replace myserver in the above file with the fully qualified domain name of the server you are creating a certificate for. Its a good idea to automate this if you want the process to be repeatable, a suggestion would be to copy the config file and have your script replace this entry. If you do not do this then Google Chrome may flag your certificate as insecure.

The pipeline we’ll create for creating certificates for servers

3. Creating a private key

We’ll create a private key for our root certificate by entering the following at the command prompt:

openssl genrsa -aes256 -out rootcertificate.key 4096

You will be asked for a pass phrase:

Enter pass phrase for rootcertificate.key: my_root_ca_password

Obviously replace my_root_ca_password with your own unique password. It will be used later in creating certificates. It’s important that the password and the rootcertificate.key file that is created is kept secret and safe. Exposing these will potentially compromise all certificates you create.

4. Creating the root certificate

To create your certificate (with filename rootcertificate.crt) enter the following at the command prompt:

openssl req -config openssl.cnf -key rootcertificate.key -new -x509 -days 9999 -sha256 -extensions v3_ca -out rootcertificate.crt

You will be asked for your pass phrase (what you replaced my_root_ca_password with) as well as having to enter a few other questions:

Enter pass phrase for rootcertificate.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
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]:US
State or Province Name (full name) [NY]:NY
Locality Name (eg, city) [New York]:New York
Organization Name (eg, company) [Example, LLC]:My Company LLC
Common Name (e.g. server FQDN or YOUR name) [Example Company]:My Company Root CA
Email Address [test@example.com]:

The important question to answer is the Common Name. Other entries are optional.

You now have 2 files created called rootcertificate.key and rootcertificate.crt.

The file rootcertificate.crt can be made publicly available and can be installed on any computer or mobile device so that created certificates (in the steps below) will be trusted.

5. Creating a server certificate

This section will show you how to create a certificate for a particular server that has been signed by your root certificate.

We’ll create a private key and a certificate signing request (CSR) for a server whose name is myserver:

openssl req -new -nodes -sha256 -keyout myserver.key -config openssl.cnf -out myserver.csr -newkey rsa:2048 -subj "/C=US/ST=/L=/O=/CN=myserver"

Be sure to replace the myserver part of CN=myserver with the full computer name of the server. This creates two files: myserver.key and myserver.csr

Important: notice that we specify the config file called openssl.cnf. In this file there a server specific setting that we should set which is the subject alternative name (subjectAltName). It appears in the file under the [ alternative_names ] section, here you can specify one or more alternative names for the server. Eg blar.com, www.blar.com, mail.blar.com

We can now create a certificate for the server using this command:

openssl x509 -sha256 -extfile openssl.cnf -extensions x509_ext -req -in myserver.csr -CA rootcertificate.crt -CAkey rootcertificate.key -CAcreateserial -out myserver.crt -days 9999 -passin pass:my_root_ca_password

Again, replace my_root_ca_password with the pass phrase you set when creating the private key for the root certificate.

You now have created the server certificate file myserver.crt and you have the associated private key in the file myserver.key. One thing you may want to do is bundle both together as a .pfx file so that they can be installed on the server. To do this:

openssl pkcs12 -export -in myserver.crt -inkey myserver.key -out myserver.pfx -certfile rootcertificate.crt -passout pass:mypassword

Make sure to replace mypassword with the password you want to use (this will be required to install the pfx file).

At this point you have everything you need to install the server’s certificate and access the server from a client by installing the rootcertificate.crt on client machines. The following are examples of how to do this with Microsoft IIS for the server and IOS / Windows PCs for the clients.

6. Installing the Server Certificate

These instructions are for a Windows server running IIS:

  • Copy myserver.pfx to the server and double click it
  • Choose Store Location of “Local Machine
  • Click Next through the wizard entering the certificate password
  • Choose the option “Automatically select the certificate store based on the type of certificate

Next we can bind the certificate to your website in IIS:

  • Open IIS Manager (Press start, type “IIS” and press Enter)
  • Open Sites in the tree view on the left and select the website
  • Click Bindings… in the menu on the right hand side
  • Edit the https binding (or add it)
  • From the SSL certificate drop down choose your certificate
  • Press OK and Close the site binding window

7. Clients trusting us

To get clients (eg web browsers, mobile devices) to trust your certificate you must install the Root Certificate (rootcertificate.crt) on the client (usually in the “Trusted Root Certification Authorities” area).

Installing on Windows

Here’s how to manually install the root certificate (This would normally be done by an I.T dept by Group Policy):

  • Double click the rootcertificate.crt file
  • Click the Install Certificate… button
  • Click next, the choose “Place all certificates in the following store
  • Choose Browse and select “Trusted Root Certification Authorities
  • Click OK and finish the installation

Your web browser should now trust any certificates that have been signed by your root certificate.

Installing on IOS

Two options for installing rootcertificate.crt on iOS include:

  • Email rootcertificate.crt and access that mail attachment on the iOS device in the mail application.
  • Make rootcertificate.crt accessible on a web page and on the iOS device use safari to open the file

After either option an “Install Profile” page will appear:

  • Press the Install button
  • Enter your passscode on the device
  • Press the Install button again on the warning page
  • The certificate should appear as “verified”. Press Done

Finally….

Thanks for checking out this guide. It covers a simple way to create server certificates. There are other best practices around this such as creating intermediate certificates which are used to create the server certificates but this adds additional complexity. I hope this helps some people out — i wrote it as googling around didn’t provide sufficient answers, if you have questions or comments feel free to reach out in the comments or on twitter @damiantarnawsky

--

--

Damian
Coding Snippets

I’m a software architect for my day job and work on a lot of side projects around mobile tech in my free time.