Setup Self-Signed Certificates & Trusting them on OS X

Wednesday, March 11, 2015 6:43 AM

Last week I put together two sample Apps for Office for use at the hackathon at ng-conf. Two two apps, one for Excel & one for Outlook, were a bit different from your typical App for Office because of a few things:

These decisions were made because the majority of the audience used OSX and the goal was to get people aware of and ideally interested in building Apps for Office. Well it worked!

If you aren’t familiar with Apps for Office, in a nutshell you create an XML manifest file that registers the app & points to a website. The app is then run as a website within the Office client. This website can be publicly accessible but during development you likely want to run off localhost for speed & simplicity. For the host Office client to load the app, it must be at an HTTPS endpoint. When you’re on Windows, setting up a self-signed certificate isn’t hard… Windows does this for you.

But I found getting this setup on OSX is no small feat. There are three things I had to do:

  • Setup a web server: There are plenty of options for this. If I was going to make just a static site, I’d use superstatic. But getting this to respect an SSL cert was not easy so I moved on and just created a simple express server.
  • Create a self-signed certificate: Again, not terribly hard. On Windows I use the makecert.exe tool & on OSX I used openssl.
  • Configuring my machine to trust the self-signed cert: This turned into a much more un-intuitive process than I expected.

Therefore in the interest of using my blog as a “note-to-self”, here’s how I did it.

The Goal

The ultimate goal was to get a web server locally that served a static site on HTTPS and have the browser trust the certificate. Here’s the script I used to host the site (notice it needs) two certificates that I’m loading in lines 7-10:

Then I needed the browser to not show this:

Rather I needed it to show this when hitting the site:

So here’s how you do it:

Create Self-Signed Certificate & Key

The first step is to create the self-signed certificate & key that will be used by the web server.

Open a Terminal prompt and enter the following command:

$ openssl genrsa -out localhost-key.pem 1024

Next, create the certificate request:

$ openssl req -new -key localhost-key.pem -out localhost.csr

At this stage the openssl tool will prompt you for a few more items. These values will get added to the certificate request that you are generating to get the private key. What follows is an example of some options you can use. The important point is to use localhost for the Common Name request.

Now create the certificate from the certificate request:

At this point you have the public-private key pair for the certificate.

You can use these in the files in the script at the top of these instructions. However you will notice that, as stated previous, the browser won’t respect the certificate. You will see a Your connection is not private message in Chrome and the URL will show an error with the certificate:

To fix this, you need to add the certificate as a trusted root authority.

Add the Certificate as a Trusted Root Authority

This process wasn’t anything close to being intuitive… but here it is anyway.

Assuming you are using the Chrome browser…

In the address bar, click the little lock with the X. This will bring up a small information screen. Click the button that says “Certificate Information”.

Click and drag the image to your desktop. It looks like a little certificate.

Open the Keychain Access utility in OS X. Select the System option on the left. Click the lock icon in the upper-left corner to enable changes.

Click the plus button at the bottom and select the localhost.cer file you copied to the desktop. In the dialog that comes up, click Always Trust.

After localhost gets added to the System keychain, double-click it to open it again. Expand the Trust section and for the first option, pick Always Trust.

At this point everything has been configured. Quick Chrome and all other browsers (this is required), fire up the web server and try again to navigate to the local HTTPS site. The browser should report it as a valid certificate: