Building a simple Node.js crypto hash server


The Crypto module is one of the important modules available for Node.js, and allows you to use it for encrypting content, creating digests and creating public-key signatures. In this post we will work with creating a simple message digest from some given content. Here we will create a Node.js server that responds with a cryptographic hash for the content provided. e.g if we query with the following url, passing the text helloworld and the hash function name md5 the server will return the digest of the text. Note that the crypto module requires OpenSSL to be available on the underlying platform. Although a toy program, this is an exercise in using the ‘crypto’ and ‘querystring’ modules.

http://localhost/?text=helloworld&algo=md5

We will get the following response from the server. This is the md5 digest of the text helloworld. Besides md5 we have support for sha1, sha256, sha512.

fc5e038d38a57032085441e7fe7010b0

Changing the algo query parameter to sha1 will return the following.

6adfb183a4a2c94a2f92dab5ade762a47889a5a1

The code uses several modules, so you need to include them first. We also define the supported hash algorithms for our script with the variable ‘algorithms’.

var http        = require('http'), // for creating the server
    crypto      = require('crypto'), // for cryptographic tools
    url         = require('url'), // for parsing urls
    querystring = require('querystring'); // for extracting query strings
 
var hash , algorithms = ['md5', 'sha1', 'sha256', 'sha512'];

Once the above files are included we first initialize the server and start listening for client requests. We use the default port 80.

// creates a new httpServer instance
http.createServer(function (req, res) {
 
  // All the cryptographic code will be included here
 
 
  // the server will listen on the default port, port 80
}).listen(80);

In the server request callback we first retrieve the url query parameters and check if the hash algorithm provided in the query is valid. If not we send an error message to the browser. The ‘query’ variable holds the parsed query parameters.

// query variable content
{ text: 'helloworld', algo: 'md5' }
// creates a new httpServer instance
http.createServer(function (req, res) {
 
  // Parse the query string from the url
  var query = querystring.parse(url.parse(req.url).query);
 
  // Check if hash algorithm supplied in the query is supported
  if(algorithms.indexOf(query.algo) > -1) {
    // Hash algorithm ok
  } else {
  // Unsupported Hash algorithm given, throw an error to the browser
  }
 
  // close the response
  res.end();
 
  // the server will listen on the default port, port 80
}).listen(80);

If no errors are found the following code generates the hash digest.

    // Create a hash with the selected algorithm
    hash = crypto.createHash(query.algo);
 
    // Updates the hash content with the given data
    hash.update(query.text);
 
    // write some headers so the browser knows 
    // what type of content we are sending
    res.writeHead(200, {'Content-Type': 'text/html'});
 
    // write the hash digest to the browser
    // Output encoding can be 'hex', 'base64' or 'binary'
    res.write(hash.digest('hex'));

The complete Node.js server code is shown below which you can run from the command line.

node make-digest.js

The server is now listening on port 80, which we can access from the browser as below.

http://localhost/?text=helloworld&algo=md5
// File name : make-digest.js
 
var http        = require('http'),
    crypto      = require('crypto'),
    url         = require('url'),
    querystring = require('querystring');
 
var hash , algorithms = ['md5', 'sha1', 'sha256', 'sha512'];
 
// creates a new httpServer instance
http.createServer(function (req, res) {
 
  // Get the query parameters from the url
  var query = querystring.parse(url.parse(req.url).query);
 
  // Check if hash algorithm supplied in the query is supported
  if(algorithms.indexOf(query.algo) > -1) {
    // Create a hash with the selected algorithm
    hash = crypto.createHash(query.algo);
 
    // Updates the hash content with the given data
    hash.update(query.text);
 
    // write some headers so the browser knows 
    // what type of content we are sending
    res.writeHead(200, {'Content-Type': 'text/html'});
 
    // write the hash digest to the browser
    // Output encoding can be 'hex', 'base64' or 'binary'
    res.write(hash.digest('hex'));
 
  } else {
 
    res.writeHead(200, {'Content-Type': 'text/html'});
 
    // write some content to the browser that your user will see
    res.write('Check for correct url parameters: ');
    res.write('?text=content-text&algo=hash-algorithm');
  }
 
  // close the response
  res.end();
 
  // the server will listen on the default port, port 80
}).listen(80);

This site is a digital habitat of Sameer Borate, a freelance web developer working in PHP, MySQL and WordPress. I also provide web scraping services, website design and development and integration of various Open Source API's. Contact me at metapix[at]gmail.com for any new project requirements and price quotes.

Your thoughts