In this digital era, security and data privacy is a top concern for developers. We should not let our user’s data be stolen by irresponsible people. 3 common cryptography techniques are used to secure your data as developers. Those techniques are:
- Hash
- Symmetric Encryption
- Asymmetric Encryption
In this article, we will look at specifically hash. Let’s see the implementation in NodeJS.
NodeJS Library for Hash Cryptography And Its Algorithm
To create a hash, we can use a built-in nodejs library that is crypto
. you just have to import them like this:
let crypto = require("crypto")
This library supports many kinds of hash algorithms. To get all of the supported algorithms, you can use this method:
let crypto = require("crypto") console.log(crypto.getHashes()) // ['RSA-MD5','RSA-RIPEMD160','RSA-SHA1','RSA-SHA1-2','RSA-SHA224', // 'RSA-SHA256','RSA-SHA3-224','RSA-SHA3-256','RSA-SHA3-384', // 'RSA-SHA3-512','RSA-SHA384','RSA-SHA512','RSA-SHA512/224', // 'RSA-SHA512/256','RSA-SM3','blake2b512','blake2s256', // 'id-rsassa-pkcs1-v1_5-with-sha3-224','id-rsassa-pkcs1-v1_5-with-sha3-256', // 'id-rsassa-pkcs1-v1_5-with-sha3-384','id-rsassa-pkcs1-v1_5-with-sha3-512', // 'md5','md5-sha1','md5WithRSAEncryption','ripemd','ripemd160', // 'ripemd160WithRSA','rmd160','sha1','sha1WithRSAEncryption','sha224', // 'sha224WithRSAEncryption', 'sha256','sha256WithRSAEncryption','sha3-224', // 'sha3-256','sha3-384','sha3-512','sha384','sha384WithRSAEncryption', // 'sha512','sha512-224','sha512-224WithRSAEncryption', // 'sha512-256','sha512-256WithRSAEncryption','sha512WithRSAEncryption', // 'shake128','shake256','sm3','sm3WithRSAEncryption','ssl3-md5', // 'ssl3-sha1']
As you can see we can use many algorithms, 2 of them are sha256
and sha512
which is the most popular one.
Basic Hash Cryptography in NodeJS
The first method in crypto
library that is used to hash is createHash()
. This method provides a basic hashing functionality in nodejs. You will probably not use this method in real-world applications because it is just not as safe as the other method. To use this method, you can look at this code piece:
let crypto = require("crypto")
let hash = (text) => {
let hash = crypto.createHash("sha256")
hash.update(text)
return hash.digest("hex")
}
let compare = (text, hashedText) = {
let hashed = hash(text)
return (hashed === hashedText) ? true : false
}
module.exports = {
hash,
compare
}
Notes!
Don’t use this method for hashing passwords, it is not safe!
In this example, we use SHA256
algorithm, alternatively, you can use SHA512
to create a stronger hash.
HMAC Cryptography in NodeJS
HMAC is a Hash-based Message Authentication Code. It is a cryptographic authentication technique that uses a hash function and a secret key.
The most popular HMAC techniques are HMAC-SHA256 and HMAC-SHA512.
To create a hmac, you can use createHmac()
method. This method is usually combined with encryption cryptography such as AES to create a message authentication code. We will try to create an HMAC-SHA256 as an example of how to use this method:
let crypto = require("crypto")
let hash = (text) => {
let hmac = crypto.createHmac("sha256", "mysupersecret")
hmac.update(text)
return hmac.digest("hex")
}
let compare = (text, hashedText) => {
let hashed = hash(text)
return (hashed === hashedText) ? true : false
}
module.exports = {
hash,
compare
}
You can see that it uses a secret mysupersecret
to hash the text. To create SHA512, you just have to change the hash algorithm from sha256
to sha512
on the code snippet above.
Notes!
Don’t use this method for hashing passwords, it is not safe!
PBKDF2 Cryptography in NodeJS
PBKDF2 is Password-Based Key Derivation Function (version) 2. It is a hash technique that is used specifically for generating passwords because it is deliberately slow to compute by using many iteration processes.
The most popular PBKDF2 techniques are PBKDF2-HMAC-256 and PBKDF2-HMAC-512.
We will try to create a PBKDF2-HMAC-SHA256 as an example of how to use this method:
let crypto = require("crypto)
let hash = (salt, text) => {
let algorithm = "sha256"
let iteration = algorithm === "sha512" ? 210000 : 600000
return new Promise((resolve, reject) => {
pbkdf2(text, salt, iteration, 64, algorithm, (err, derivedKey) => {
if (err) return reject(err)
return resolve(salt + "." + derivedKey.toString("hex"))
})
})
}
let compare = async (text, hashedText) => {
let salt = hashedText.split(".")[0]
let hashed = await hash(salt, text)
return (hashed === hashedText) ? true : false
}
module.exports = {
hash,
compare
}
Before calling the hash function, you can generate the randomSalt
value just like this
let randomSalt = crypto.randomBytes(16).toString("hex")
Also, notice that we return the randomSalt
together with the derivedKey
in this hash function example. It is common practice that we use a unique salt every time we create a new password and embed it together with the password to make the password unpredictable.
When comparing the text
and hashedText
, first we must extract the salt
and then generate the hash
with the extracted salt
value.
Scrypt Cryptography in NodeJS
Scrypt is the same as pbkdf2, a password-based key derivation function. Besides being deliberately slow, it is designed to require a large (and adjustable) amount of memory to compute. The purpose of this is to make it harder to crack parallelly using devices like GPGPUs or custom ASIC / FPGA hardware.
To use this method, you can look at this code piece:
let crypto = require("crypto)
let hash = (salt, text) => {
return new Promise((resolve, reject) => {
pbkdf2(text, randomSalt, 64, (err, derivedKey) => {
if (err) return reject(err)
return resolve(randomSalt + "." + derivedKey.toString("hex"))
})
})
}
let compare = async (text, hashedText) => {
let salt = hashedText.split(".")[0]
let hashed = await hash(salt, text)
return (hashed === hashedText) ? true : false
}
module.exports = {
hash,
compare
}
Same as PBKDF2, Before calling the hash function, you can generate the randomSalt
value just like this
let randomSalt = crypto.randomBytes(16).toString("hex")
Notice that we also return the randomSalt
together with the derivedKey
to make the password unpredictable.
That’s it. Those are the 4 types of hash that we can use in NodeJS using the crypto library.