npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pwd-hasher

v2.0.0

Published

simple password hashing with support for salt, secret pepper, and brute-force salt

Downloads

18

Readme

Pwd Hasher

Simple password hashing with support for salt, secret pepper, and brute-force salt.

Install dependency

npm install --save pwd-hasher

Usage

import { Hasher } from 'pwd-hasher';

const hasher = new Hasher({ secretPepper: 'shhh', workFactor: 10 });

const hashed = await hasher.hash('my-password');

const invalid = await hasher.compare('incorrect-password', hashed); // false
const valid = await hasher.compare('my-password', hashed); // true

API

Constructor

const hasher = new Hasher({ secretPepper, workFactor });

Creates a new Hasher object.

The secretPepper should be a string which is known only to the webserver (it should not be stored in the same database as the hashes) and must not change (if it changes, all passwords will become invalid). Typically this would be provided as an environment variable to the web server during deployment. By default this is a blank string ''.

The workFactor should be an integer which controls the amount of work required to generate the hash. This should be tuned to take the longest possible time which still gives a good user experience when logging in, as this will provide the greatest protection for offline attacks against the password hash database. This value can and should change over time; if you deploy your application to a more powerful server, the number should be raised. Each increment approximately doubles the required work. By default this is 10.

hash

const hashed = await hasher.hash(password);

Hashes the given password using a random salt and brute-force salt.

The algorithm used is bcrypt(sha512(password+bruteSalt+secretPepper)) (bcrypt provides the salt). This avoids password length restrictions. The bruteSalt is a random integer from 0 to 7 and provides additional protection against brute-force attacks (incorrect passwords will take, on average, approximately twice as much effort to invalidate as correct passwords will take to validate).

compare

const match = await hasher.compare(password, hash);

Checks a password against the given hash. The configured secretPepper must match the value used when generating the original hash. The workFactor can be different; this will always use the work factor stored with the hash.

needsRegenerate

const regenerate = hasher.needsRegenerate(hash);

Returns true if the hash's work factor is lower than the currently configured work factor. In this scenario, you should re-hash the password during a successful login. For example:

async function login(user, password) {
  const hash = await myDB.getUserHash(user);
  const success = await hasher.compare(password, hash);
  if (!success) {
    return false;
  }
  if (hasher.needsRegenerate(hash)) {
    const newHash = await hasher.hash(password);
    await myDB.saveUserHash(user, newHash);
  }
  return true;
}

This will ensure that old passwords are slowly updated to the latest work factor as users log in to the application, even if the user does not update their password.