Part 2: Installation & Configuration of SSL for NodeJS.
Table of Content:
- Part 1: Installation & Configuration of SQL Server Driver for NodeJS.
- Concept
- Note
- Requirement
- Create Certificates
- Deploy NodeJS test server
- PHP Curl script example
- Part 3
Concept
In order to communicate securely, we need to encrypt the connection between our client (PHP) and server (NodeJS) via SSL protocol.
Note
For this article, we assume that our NodeJS server IP is: 125.0.0.1 and the PHP (XAMPP) server IP is: 192.168.0.1
LET’S BEGIN…
Requirement
- OpenSSL. I suggest using Linux box version.
First we create self-signed certificate for our CA, server and client. The server (NodeJS) will be using the ca.crt, server.crt and server.key. The client (PHP) will be using ca.crt, client.crt and client.key.
Create Certificates
- Create the self-signed CA Key and Certificate for signing Client Certs:
openssl genrsa -des3 -out ca.key 4096 openssl req -new -x509 -days 365 -key ca.key -out ca.crt
- Create the Server Key, CSR, and Certificate:
<TODAY> is in the format: YYMMDDHHMM
Make sure you enter 125.0.0.1 for the hostname field.openssl genrsa -des3 -out server.key 1024 openssl rsa -in server.key -out server.key openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial <TODAY> -out server.crt
- Create the Client Key, CSR, and Certificate:
Make sure you enter 125.0.0.1 for the hostname field.openssl genrsa -des3 -out client.key 1024 openssl rsa -in client.key -out client.key openssl req -new -key client.key -out client.csr openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial <TODAY> -out client.crt
If you decide to use the real CA (VeriSign, GeoHost, etc), you can send your CSR files to them.
Deploy NodeJS test server
Now we ready for the server. Create folder ssl and inside it create folder cert. Copy files ca.crt, server.key and server.crt to folder ssl/cert. Here’s the server NodeJS code:
var https = require('https'), // module for https fs = require('fs'); // required to read certs and keys var options = { key: fs.readFileSync('cert/server.key'), cert: fs.readFileSync('cert/server.crt'), ca: fs.readFileSync('cert/ca.crt'), requestCert: true, rejectUnauthorized: false }; https.createServer(options, function (req, res) { if (req.client.authorized) { res.writeHead(200, {"Content-Type": "application/json"}); res.end('{"status":"approved"}'); console.log("approved"); } else { res.writeHead(401, {"Content-Type": "application/json"}); res.end('{"status":"denied"}'); console.log("denied"); } }).listen(443,'125.0.0.1');
Save it with name ssl.js, and start the server with command node ssl.js
PHP Curl script example
Now copy your ca.crt, client.key and client.crt somewhere (I use XAMPP htdocs/ssl/cert folder). Create index.php inside htdocs/ssl with this simple code to test the server:
$tuCurl = curl_init(); curl_setopt($tuCurl, CURLOPT_URL, "https://125.0.0.1/"); curl_setopt($tuCurl, CURLOPT_PORT , 443); curl_setopt($tuCurl, CURLOPT_VERBOSE, 0); curl_setopt($tuCurl, CURLOPT_HEADER, 0); curl_setopt($tuCurl, CURLOPT_SSLVERSION, 3); curl_setopt($tuCurl, CURLOPT_SSLCERT, getcwd() . "/ssl/client.crt"); curl_setopt($tuCurl, CURLOPT_SSLKEY, getcwd() . "/ssl/client.key"); curl_setopt($tuCurl, CURLOPT_CAINFO, getcwd() . "/ssl/ca.crt"); curl_setopt($tuCurl, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, 1); $tuData = curl_exec($tuCurl); if(!curl_errno($tuCurl)){ $info = curl_getinfo($tuCurl); echo 'Took ' . $info['total_time'] . ' seconds to send a request to ' . $info['url']; } else { echo 'Curl error: ' . curl_error($tuCurl); } curl_close($tuCurl); echo $tuData;
Now open the URL http://192.168.0.1/ssl and you should see approved message which is sent by NodeJS server. Try to change the curl SSL and you should see denied message instead.
to be continued in Part 3…
Credits:
- Drupal Meetup Jakarta, Friday November 30th 2012.
- http://blog.nategood.com/client-side-certificate-authentication-in-ngi
- http://blog.nategood.com/nodejs-ssl-client-cert-auth-api-rest
- http://php.net/manual/en/book.curl.php