title: Never see localhost HTTPS warnings again
url: https://certsimple.com/blog/localhost-ssl-fix
hash_url: 63e224124ceedf8c6e787bbbc7896165

<p>If you've done any web development you'll be used to seeing this every time you connect to <code>https://localhost</code>:</p>
<p><amp-img layout="responsive" alt="an image" src="/images/blog/localhost-ssl-fix/untrusted-localhost.png"/></p>
<p>Unless your OS has already been hacked - at which point it's already too late, since the attacker could have already installed anything they wanted - <code>localhost</code> is likely to still be yourself and not an attacker as the message suggests.</p>
<p>If you're tired of seeing the warning, and the two clicks required to show localhost over HTTPS, you can make your machine trust itself. It takes <strong>less than ten minutes</strong>, there's only one command, and you'll never see localhost SSL warnings again.</p>
<h2 id="step-1-create-a-self-signed-root-certificate">Step 1. Create a self-signed root certificate</h2>
<p>Start 'Applications' &gt; 'Utilities' &gt; 'Keychain Access'</p>
<p>Inside KeyChain access, in the menu bar, click 'Keychain Access' &gt; 'Certificate Assistant' &gt;  'Create a Certificate'</p>
<p><amp-img layout="responsive" alt="an image" src="/images/blog/localhost-ssl-fix/create-a-certificate.png"/></p>
<p>On the 'Create a Certificate' screen:</p>
<ul>
<li>Change 'Name' to 'localhost'</li>
<li>Leave 'Identity Type' as 'Self Signed Root'</li>
<li>Change 'Certificate Type' to 'SSL Server'</li>
</ul>
<p><amp-img layout="responsive" alt="an image" src="/images/blog/localhost-ssl-fix/create-your-certificate.png"/></p>
<p>Then hit 'Create'. OS X will tell you that a self signed certificate doesn't provide the security guarantee of a certificate assigned by a CA, which is true: <a href="/blog/domain-validated-ssl">encryption has very little value without identity.</a>. However your self signed certificate is only for your local machine, and not for anyone else to trust.</p>
<p>Hit 'Continue' to indicate you understand.</p>
<p><amp-img layout="responsive" alt="an image" src="/images/blog/localhost-ssl-fix/self-signed-certificates-are-worthless.png"/></p>
<p>The new certificate will be shown. Click 'Done'</p>
<p><amp-img layout="responsive" alt="an image" src="/images/blog/localhost-ssl-fix/successfully-created.png"/></p>
<h2 id="step-2-trust-the-new-root-certificate">Step 2. Trust the new root certificate</h2>
<p>You'll be back in Keychain's list of certificates. Click the certificate you just made - it will have a gold certificate icon beside it. Search for 'localhost' if you can't see it.</p>
<p><amp-img layout="responsive" alt="an image" src="/images/blog/localhost-ssl-fix/keychain-list-of-certificates.png"/></p>
<p>Expand 'Trust'. Change 'Secure Sockets Layer (SSL)' to 'Always Trust'</p>
<p><amp-img layout="responsive" alt="an image" src="/images/blog/localhost-ssl-fix/trust-new-certificate.png"/></p>
<p>Enter your password when asked to make the change.</p>
<h2 id="step-3-use-the-key-in-your-apps">Step 3. Use the key in your apps</h2>
<p>Now you'll need to set up the private key and certificate for use in your development web server. Most openssl apps (like nginx, node, etc) typically use <code>pem</code> format keys, so we're going to export the key and change the key format into .pem.</p>
<p>Back in the list of certificates, find the private key for localhost (it will have a key icon next to it).</p>
<p>Right click the private key and export it. Select a folder, and change file format to be 'Personal Information Exchange (.p12)'. Hit 'Save'. You'll be asked to create a password to encrypt the file: you can enter one or you can just hit OK to skip. Then you'll be asked for your own password again to allow the extraction.</p>
<p><amp-img layout="responsive" alt="an image" src="/images/blog/localhost-ssl-fix/export-localhost.png"/></p>
<p>Now let's change it into a PEM file. Open Terminal, then run:</p>
<pre><code class="hljs">openssl pkcs12 -<span class="hljs-keyword">in</span> Certificates.p12 -out Certificates.pem -nodes
</code></pre><p>You'll be asked what the password is, just press enter since you didn't set the password:</p>
<pre><code class="hljs">Enter Import Password:
MAC verified OK
</code></pre><p>This creates <code>Certificates.pem</code>, a single file with both the private key and the certificate inside.</p>
<p>Since most web servers prefer seperate files, you can separate <code>Certificates.pem</code> file into separate files. I like to make a <code>~/.localhost-ssl</code> directory to put the files into, so everyone working on a project can use their own keys. Eg, put:</p>
<pre><code class="hljs">-----BEGIN CERTIFICATE-----
certificateGoesHere
-----END CERTIFICATE-----
</code></pre><p>into <code>~/.localhost-ssl/cert.pem</code>.</p>
<p>Then put:</p>
<pre><code class="hljs">-----BEGIN RSA PRIVATE KEY-----
privateKeyGoesHere
-----END RSA PRIVATE KEY-----
</code></pre><p>into <code>~/.localhost-ssl/key.pem</code>.</p>
<p>Now make your web server use <code>cert.pem</code> for the certificate and <code>key.pem</code> for the private key and  when running on localhost - this is up to your individual web server.</p>
<p>Et voila! No more localhost warnings!</p>
<h2 id="bonus-quick-command-line-https-server">Bonus: quick command line HTTPS server</h2>
<p>Sometimes you need a quick command line web server to share out a folder for a quick proof of concept. You can use your key and cert files to make a trusted HTTPS server too.</p>
<p>Install <a href="https://nodejs.org/en/download/">node</a> if you haven't already, and grab the <a href="https://www.npmjs.com/package/http-server"><code>http-server</code></a> module:</p>
<pre><code class="hljs">sudo npm install -g http-server
</code></pre><p>You can then then start and HTTPS server with:</p>
<pre><code class="hljs">http-server --ssl --cert /path/to/cert.pem --key /path/to/key.pem
</code></pre><p>This will share out your currently directory on <code>https://localhost:8080</code></p>
<p>Since that's an awful lot of typing, add this to your <code>.bash_profile</code></p>
<pre><code class="hljs"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">https</span>-<span class="hljs-title">server</span> (<span class="hljs-params"/>) </span>{
    http-server --ssl --cert ~<span class="hljs-regexp">/.localhost-ssl/</span>localhost-ssl/cert.pem --key ~<span class="hljs-regexp">/.localhost-ssl/</span>key.pem
}
</code></pre><p>You can then simply type <code>https-server</code> to share out the current directory over HTTPS.</p>
