Showing posts with label ssl. Show all posts
Showing posts with label ssl. Show all posts

Friday, June 12, 2015

Free SSL Certificates

On Wednesday I talked about how I added SSL (but actually TLS) support to Amphibian.com in response to user requests. One thing that is always a problem when trying to secure a public web site is the high cost of certificates signed by "real" certificate authorities.

In order for you to not scare away your users with dire browser warnings, any secure certificate served by your web site must be signed by an authority that ships with the browser. While it is possible to install new authorities, it is not something that 99% of people would ever do. That means you're stuck paying a yearly fee to someone for keeping your site secure.

Unless you use StartSSL.

Yes! StartSSL provides FREE server certificates with 1-year terms and is a trusted authority in all common browsers. The catch is that it can be a little tricky to request and use them.

There are three steps to the process. First, you need a certificate installed in your browser that StartSSL can use to verify that you are who you claim to be. Go to https://www.startssl.com and click on the button in the upper right that looks like an ID card and some keys.

Click on the Keys to Begin
 Then click on the link to sign-up for an account. After filling out your name, address, phone number, and email address, click "Continue" and they will email you a verification code that you need to type in on the web page.

Fill out this form with your contact information.
Don't navigate off the page until you get the code and enter it! After that, they'll generate a key and install it in your browser. Now you can authenticate yourself with their system and move on to the next step.

The second step in this process is to use the Validations Wizard to validate your domain. Click on the Validations Wizard tab and then select "Domain Name Validation" from the drop-down box.

You want Domain Name Validation
On the next screen, enter the domain name for which you desire validation. StartSSL will read the WhoIs record for that domain and offer to send a verification code to one of the email addresses listed as contacts.

Enter your domain name. No www nothing, just the domain.
If you really control this domain, you should be able to get the email for at least one of them. Assuming that is true, get the validation code from your email and enter it on the next screen. Congratulations, you just verified your domain and you can move on to step 3.

Now go to the Certificates Wizard tab and select "Web Server SSL/TLS Certificate" from the drop-down list.


The next step will be to create the private key. This is the the one you want to keep to yourself! Enter a password for it and continue to the next step. It will show you the key in a text area. Copy and paste it into a file called ssl.key and click Continue.


The next screen has you select the domain for which you are generating this certificate. A drop-down box will show you the list of all the domains that you have verified (that was the second part of this 3-part process). After that, you have to supply a single subdomain. The certificate will be good for both. Most people use "www" for this. After one final confirmation screen, they are ready to generate your certificate.

If everything went well, you should be given another text area with your certificate in it. Copy and save it to a file named ssl.cert or something with the domain name in it so you remember which one it is for.

Now you should have a private key and a certificate signed by a legitimate authority. You're all set, right? Well, almost. I know I said there are only three steps but there is maybe kinda one more. You see, the certificate is actually signed by a StartCom intermediate authority, not the ultimate root. Some platforms, such as Android devices, don't trust the intermediate already and will reject the certificate when served from your website. The solution is to make a complete key chain using the certificate from the intermediate signer combined with your server's certificate.

First, go to the Toolbox tab and then click on "StartCom CA Certificates" on the left side. The certificates for the intermediate servers will then be available for download.


My certificate, since it is one of the free ones, is signed by the Class 1 Intermediate Server. Download that certificate and then concatenate it together with your ssl.cert file.

cat ssl.cert sub.class1.server.sha2.ca.pem > combined.cert

Now use the file combined.cert instead of ssl.cert for the server certificate in your web serving application of choice (Apache, Node, Nginx, etc) and even Androids will be happy.

I've done this a couple of times now for a few different domains and it works great. It is a maybe a little involved but it is free. In this case you get even more than what you pay for! Now have a look at today's comic - view it using transport layer security if you want!

Amphibian.com comic for 12 June 2015

Wednesday, June 10, 2015

Serving Your Express App With Encryption

While today's comic has nothing to do with encryption, you can actually view it (or any of my other content) using encrypted web communications. Most people refer to this as SSL, which stands for Secure Socket Layer, but SSL is an older and now non-recommended way of securing web traffic. The current method is called TLS and stands for Transport Layer Security. Doesn't make a whole lot of difference what you call it, it's the "s" in "https" when you're viewing a page with the reasonable assurance that no one is able to spy on your network traffic.

Don't mess with my network traffic!
Before last week, Amphibian.com had no way of delivering web pages in a secure manner. Why would it need to? It's just a web comic. But after my Bitcoin Paywall comic got so insanely popular I started to get people asking why I didn't have encryption enabled. Without it, there is a small chance that someone could inject their own Bitcoin address into the response from my server and take the money you are trying to send to me. So I decided to get a server certificate signed by a real authority (more on that Friday) and enable encryption for my comics.

This of course led me to create Monday's comic in which the frogs are surrounded by danger when viewed via http://amphibian.com/177 but are much safer when viewed via https://amphibian.com/177.

Now for the technical part. In order to get my Node/Express app to serve web pages over both secure and insecure web ports, 443 and 80 respectively, I had to make a few changes.

For simple apps, you are probably familiar with listening on a port this way:

var express = require("express");
var app = express();

// ... set up routes ...

var server = app.listen(3000, function() {
    console.log("listening on port %d", server.address().port);
});

But if you want the same Express instance to handle the traffic on multiple ports, you have to use the Node http module directly to create servers and pass in the Express instance as a parameter:

var express = require("express");
var http = require("http");
var app = express();

// ... set up routes ...

var server = http.createServer(app).listen(3000, function() {
    console.log("listening on port %d", server.address().port);
});

You could of course use this technique to listen on multiple insecure ports, like 3000 and 4000 as in this example:

var express = require("express");
var http = require("http");
var app = express();

// ... set up routes ...

var server1 = http.createServer(app).listen(3000, function() {
    console.log("listening on port %d", server1.address().port);
});

var server2 = http.createServer(app).listen(4000, function() {
    console.log("listening on port %d", server2.address().port);
});

However, if you want one of the listening ports to use encrypted communications you need to use the Node https module instead of http for one of them. In the simplest possible configuration it takes just one extra parameter - an options object which contains at a minimum the private key and public certificate for the server.

var express = require("express");
var http = require("http");
var https = require("https");
var fs = require("fs");
var app = express();

// ... set up routes ...

var server1 = http.createServer(app).listen(3000, function() {
    console.log("listening on port %d", server1.address().port);
});

var sslOptions = {
    key: fs.readFileSync("/path/to/private.key"),
    cert: fs.readFileSync("/path/to/server.cert")
};

var server2 = https.createServer(sslOptions, app).listen(4000, function() {
    console.log("listening securely on port %d", server2.address().port);
});

And just like that you can enable encrypted communications in your Express web app. Now read today's comic where the frogs try to avoid upsetting the apple cart...

Amphibian.com comic for 10 June 2015