JavaScript

How to create hash from string or file using crypto module in Node.js

A hash is a way to encrypt data into a fixed-length digest. This digest serves as a signature representing the original data that hashed. The various types of hashing algorithms are available in Node.js through the crypto module.

crypto is an interface for OpenSSL functionality. This includes wrappers for OpenSSL’s hash, HMAC, cipher, decipher, sign, and verify functions.

You will see solutions to verifying file integrity with hash algorithms. Hash algorithms take an arbitrary amount of data and convert it into a manageable fixed-length representation of that data, like a signature for the original data. Hash algorithms are one-way, usually we don’t need to unhash a hashed message.

List all available Hashes in Node.js

The getHashes method is a shortcut to list all the available hashes. Run the following code to get the full list of available hashes for Node.js.

//hashList.js

const crypto = require('crypto'),
hashes = crypto.getHashes();
hashes.forEach(hash => {
 console.log(hash);
});

I received the following output:

D:\BrainBell\>node hashList.js
DSA
DSA-SHA
DSA-SHA1
DSA-SHA1-old
RSA-MD4
RSA-MD5
RSA-MDC2
RSA-RIPEMD160
RSA-SHA
RSA-SHA1
RSA-SHA1-2
RSA-SHA224
RSA-SHA256
RSA-SHA384
RSA-SHA512
dsaEncryption
dsaWithSHA
dsaWithSHA1
dss1
ecdsa-with-SHA1
md4
md4WithRSAEncryption
md5
md5WithRSAEncryption
mdc2
mdc2WithRSA
ripemd
ripemd160
ripemd160WithRSA
rmd160
sha
sha1
sha1WithRSAEncryption
sha224
sha224WithRSAEncryption
sha256
sha256WithRSAEncryption
sha384
sha384WithRSAEncryption
sha512
sha512WithRSAEncryption
shaWithRSAEncryption
ssl2-md5
ssl3-md5
ssl3-sha1
whirlpool

Creating a hash from string

You have examined the different types of hashes that are available in Node.js. Let’s implement a hash in order to secure a message, for example, create a password hash for storing in a database.

The following example creates a hash using sha1 algorithm, uses the hash to encode a password, and then extracts the digest of the data to store in the database:

const pwd = 'a3xpu#XY5',
hashPwd   = crypto.createHash('sha1')
 .update(pwd)
 .digest('hex');

console.log(hashPwd);
//f9862f0ed8f093afb7f6d2165aa63a69dda262da

The createHash function accepts an algorithm, which must be an acceptable algorithm to create a hash.

After you pass the algorithm to the createHash method, send a message that you want to have hashed to the update(message[,encoding]) method. If not, encoding is defined, which could be utf8, ascii, or binary, then the message is assumed to be a buffer.

The digest encoding is set to hex (hexadecimal). Encoding is binary, by default, and base64 can also be used.

Creating a hash from file using whirlpool algorithm

The whirlpool algorithm produces a 512-bit hash and is not known to have collision vulnerabilities. We’ll use whirlpool algorithm to hash files in our Duplicate Files Finder app to generate file signatures and then compare these hash signatures to find the duplicate files.

//whirlpoolHash.js

const len = 4096,
pos = 0, offset =0,
file = './video.mp4',
buff = Buffer.alloc(len);

fs.open(file, 'r', (err, fd) => {
 fs.read(fd, buff, offset, len, pos, (err, bytes, buff) => {
 const hash = crypto
 .createHash('whirlpool')
 .update(buff)
 .digest('hex');
 console.log(hash);
 /* prints following hash
  ea8f4f1c979cd850bde3dd731b283c31ed6658c3e01
  d3f47538967e07a9d37cfca8cf22e744bd6f14977b9
  c81fc116c4009dd93018ff5526602e35b2e305f1ac
 */
 });
});

The above code shows how to read the header of a file. We just read 4Kb instead of the entire file. The information of a file, such as file type, are stored in the file header, so we just used the 4Kb chunk of file to generate the hashed signature of the file.

In next tutorial I’ll explain:

  • What is a file descriptor
  • How to open a file for reading, writing or appending
  • How to set the mode (permissions) when writing a file
  • How to close file descriptor