Salt Hash passwords using NodeJS crypto

January 18, 2016
by Rahil Shaikh

This article will explain you to salt hash passwords using Node.js Crypto.
Here we’ll not go into details comparing the pros and cons of different ways of storing passwords, rather we’ll see how we can implement salt hashing mechanism for storing passwords in NodeJS. Stay rest assured that this is one of the better ways if not the best way to store passwords.

What is this technique?

Salt hashing is a technique in which we take the user entered password and a random string of characters called as salt, hash the combined string with a sutaible hashing algorithm and store the result in the database.

Why Salt Hash?

Since hashes of the same password are the same, they are much easier to crack using lookup tables and rainbow tables, here someone pre-calculates the hashes of common passwords and stores them for others to use. Having same password hash for two or more users also makes it easier for the attacker to predict the password. So as a rule of thumb, no two users should have the same password hash. Adding salt to a password and then hashing the result reduces the possibility of having duplicate hashes and if your salt length is long enough, chances are minimal.

Practical Implementation

Well in practice you would do the following.

Creating and Storing password

  1. Take the user password
  2. Generate a salt(String of random characters)
  3. Combine the salt with the user entered password
  4. Hash the combined string with a suitable cryptographic algorithm.
  5. Store the result as the password and also store the salt along side.

Validating user password

  1. Validate the username and fetch the hashed result and salt from the database
  2. Combine the user entered password with the salt stored for that user.
  3. Hash the combined string with the same cryptographic algorithm used at the time of creating user.
  4. Compare the result with the stored hash.

In this article we won’t be building a complete end to end application, instead we will see the code to salt-hash passwords using Node.js Crypto
 

Lets See the code

First of all require the crypto module. You don’t need to install the module separately it is already available with Node.js, just require it.
 

index.js
'use strict';
var crypto = require('crypto');

 

Function to generate Salt

We will use crypto’s randomBytes function to generate a string of random character which will be used as salt.

index.js
/**
 * generates random string of characters i.e salt
 * @function
 * @param {number} length - Length of the random string.
 */

var genRandomString = function(length){
    return crypto.randomBytes(Math.ceil(length/2))
            .toString('hex') /** convert to hexadecimal format */
            .slice(0,length);   /** return required number of characters */
};

 

Hashing the password along with salt

Use a suitable hashing algorithm according to the time(year) you are reading this. With the surge in the computing power cryptographic hashing techniques are subject to compromise, so if you use an old hashing algorithm you might be running a security risk. Here we have used sha512.

index.js
/**
 * hash password with sha512.
 * @function
 * @param {string} password - List of required fields.
 * @param {string} salt - Data to be validated.
 */

var sha512 = function(password, salt){
    var hash = crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */
    hash.update(password);
    var value = hash.digest('hex');
    return {
        salt:salt,
        passwordHash:value
    };
};

 
Now lets create a function that will use the above function to generate the hash that should be stored in the database as user’s password.

index.js
function saltHashPassword(userpassword) {
    var salt = genRandomString(16); /** Gives us salt of length 16 */
    var passwordData = sha512(userpassword, salt);
    console.log('UserPassword = '+userpassword);
    console.log('Passwordhash = '+passwordData.passwordHash);
    console.log('nSalt = '+passwordData.salt);
}

saltHashPassword('MYPASSWORD');
saltHashPassword('MYPASSWORD');

 
Notice we are invoking the saltHashPassword twice with the same parameter value just to show you how the result of the hash would be different for the same user password.
Now lets have a look at the complete file all together.

index.js
'use strict';
var crypto = require('crypto');

/**
 * generates random string of characters i.e salt
 * @function
 * @param {number} length - Length of the random string.
 */

var genRandomString = function(length){
    return crypto.randomBytes(Math.ceil(length/2))
            .toString('hex') /** convert to hexadecimal format */
            .slice(0,length);   /** return required number of characters */
};

/**
 * hash password with sha512.
 * @function
 * @param {string} password - List of required fields.
 * @param {string} salt - Data to be validated.
 */

var sha512 = function(password, salt){
    var hash = crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */
    hash.update(password);
    var value = hash.digest('hex');
    return {
        salt:salt,
        passwordHash:value
    };
};

function saltHashPassword(userpassword) {
    var salt = genRandomString(16); /** Gives us salt of length 16 */
    var passwordData = sha512(userpassword, salt);
    console.log('UserPassword = '+userpassword);
    console.log('Passwordhash = '+passwordData.passwordHash);
    console.log('nSalt = '+passwordData.salt);
}

saltHashPassword('MYPASSWORD');
saltHashPassword('MYPASSWORD');

 

Run the code

To run the above code, navigate to the working directory and run the following command.
node index.js

You will get the similar output.
 

output

output


 
Note. The hash result should be stored into the database along with the salt used for the hash corresponding to each user, and the same technique should be applied while validating the user login.
 

Conclusion

If you are working on any web application that stores users password, it is very easy to get things wrong, here we saw how we can store passwords using salt-hash technique which is highly recommended, however it is a request to the readers to look up at recent techniques of storing passwords from the time you are reading this article.
 

Reference links

About

Engineer. Blogger. Thinker. Loves programming and working with emerging tech. We can also talk on Football, Gaming, World Politics, Monetary Systems.

Free PDF

Subscribe and get AngularJS Tips PDF. We never spam!
First Name:
Email:

17 comments

  1. Ceddy
    |

    Hi Of all things why didn’t you create a method to verify the hash, lets say when a user logins in, do i check if the new hash matches the old one

    • |

      Hi Ceddy,
      If you carefully read the practical implementation section, you will get an idea.

      You will have to use the same function i.e ‘sha512(password, salt)’ to validate the password. Where the password would be the value user entered and salt would be fetched from the database corresponding to the login user name.
      Then you only have to compare the hash result from the function with the one stored in the database.

  2. Gilberto Leon
    |

    Thanks Ceddy,
    Precise and well explained.

    • |

      I have covered this in Validating user password section. Basically you have to fetch the salt and hash from db based on the username or email. Then combine the user-entered pwd with that salt, hash it with the same hashing technique and finally compare the result with the hash fetched from the db.

    • Ceddy
      |

      I think Rahil pointed it out correctly, you save the salt that you used to generate the hash, then when User logs in again, you will get the user’s ID or username and find the salt you used to create their hash, then you combine the password the user entered plus the salt stored for that user, if you generate the same hash then login success else password incorrect!

  3. FakeName
    |

    Thank you very much

  4. |

    very nice explaination

  5. |

    It would be great to have a both sides hash example with complete communication and passing salt here to there… I never really found a complete example of “passing salts to client to hash and get it back….” authentication. If you could do this I appreciate.

    • |

      Hashing is supposed to be done on server side and you don’t need to pass the salt to client.

  6. tom
    |

    totally insecure read what owasp say about sha hashing its too fast and why any site using this must be considered insecure http://www.owasp.org

    • |

      You may use hashing mechanisms as per current security standards. This post Aims to highlight the salt-hashing mechanism. What hashing algo you use does not affect the process.

  7. Omar
    |

    Thanks, I am gonna use this code in my project 😀

    • Rahil Shaikh
      |

      Sure! You are welcome 🙂

  8. David
    |

    Please read this

    https://codahale.com/how-to-safely-store-a-password/

    It will clearly explain why using SHA512, even with salt, is a bad idea.

    In short, by using a hashing algorithm not suitable for passwords, a user password can be cracked up to a million times faster than with proper hashing techniques. You cannot claim “this is one of the better ways if not the best way to store passwords”.

    For node you should be able to use something like https://www.npmjs.com/package/bcrypt-nodejs instead

    • Rahil Shaikh
      |

      When I say “this is one of the better ways if not the best way to store passwords”, I mean that salt-hashing is a much better technique as compared to other password storing techniques viz. hashing/ encryption. Mind you the emphasis here is to explain to the readers the concept of salt-hash with an example and not on the hashing algorithm used. And I don’t see the above article explaining what salt hash is. Both of the articles cover different things and it is evident from the title itself.

      Also, I think you are overthinking here, The only way salt-hash can be broken is by doing a brute-force attack where you try every possible combination. Other techniques such as the popular rainbow tables won’t work as well (I hope you know why). With salt hash every hash in the database is different, so if one password is carcked others are still safe. And that is ofcourse after considering that the hacker has access to the database and of course he knows how the salt is added to the passwords before hashing.

      P.S Nothing escapes brute force. Even bycrypt says it slows it down (which is an upside), but it can never avoid it.

Leave a Comment