Passwords are not stored as plain text for obvious security reasons. There are several npm packages already in place for password encryption such as bcrypt.js, password-hash etc.

This article does not aim to provide a better solution to the ones already provided by the existing libraries, rather it tends to shed some light on how the implementation works under the hood.

Getting Started

I assume that you already created a project. Now go ahead and create a file named custom-bcrypt.js.

Copy the snippet below into the custom-bcrypt.js file:

const md5 = require("md5");

module.exports = {
   * @param { string } rawPass - the password to be hashed
   * @param { object } [options={}] - object containing salt and rounds
   * @returns {string} 
  hash(rawPassword, options = {}) {
     * salt is optional, if not provided it will be set to current timestamp
    const salt = options.salt ? options.salt : new Date().getTime();

     * rounds is optional, if not provided it will be set to 10
    const rounds = options.rounds ? options.rounds : 10;
    let hashed = md5(rawPassword + salt);
    for (let i = 0; i <= rounds; i++) {
      hashed = md5(hashed);
    return `${salt}$${rounds}$${hashed}`;
   * @param {string} rawPassword - the raw password
   * @param { string } hashedPassword - the hashed password
   * @returns
  compare(rawPassword, hashedPassword) {
    try {
      const [ salt, rounds ] = hashedPassword.split('$');
      const hashedRawPassword = this.hash(rawPassword, { salt, rounds });
      return hashedPassword === hashedRawPassword;
    } catch (error) {
      throw Error(error.message);

Let's us explain what's going on in the code snippet above.

First, notice that we required md5 library which forms the base for the hashing. Now, install md5 in the project.

npm add md5 or yarn add md5


In cryptography, a salt is random data that is used as an additional input to a one-way function that "hashes" data, a password or passphrase. Salts are used to safeguard passwords in storage. Salts defend against a pre-computed hash attack. - wikipedia


The rounds specify the number of iterations used in the hashing. The higher the rounds the more difficult it is for hackers to guess the password using rainbow table.

Notice that in the custom-bcrypt module above, we have two functions hash and compare.

hash function

The hash function takes two arguments, the password to be hashed and the options object which is set to an empty object by default. The options object has two optional properties the salt and the rounds which are set to the current timestamp and 10 respectively. This function uses md5 to encrypt the password plus the salt as many times as the rounds. The returned value is a string consisting of the salt, rounds and the hashed value all concatenated together.

compare function

The compare function takes two arguments, the raw password to be verified and the previously hashed password. It extracts the salt and rounds from the previously hashed password and then uses it to hash the current raw password and returns a corresponding Boolean value for whether the password matches or not.

Now, let's test our custom bcrypt module. Create a file named sample.js. Copy the code below into the sample.js

const bcrypt = require('./custom-bcrypt')

const rawPassword = 'password'



console.log(bcrypt.hash(rawPassword, {salt: 'someRandomString', rounds: 20}))

console.log('password', 'someRandomString$20$199d9de71859a87cdd22e52d93f4522a'));

You can test it how ever you want, for the sake of this article, I tested it on the terminal using node sample.js.

Disclaimer: This article does not guarantee the security of encryption implemented herein.


In this article, we tried to shed some light on how password encryption works. Feel free to reach out to me if you have any question or contribution to this article. ✌️