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