Secure Password

Making Password storage safer for all
Alternatives To Secure Password
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
John7,484
2 days ago482C
John the Ripper jumbo - advanced offline password cracker, which supports hundreds of hash and cipher types, and runs on many operating systems, CPUs, GPUs, and even some FPGAs
Node.bcrypt.js6,72135,8022,6452 months ago52February 26, 202124mitC++
bcrypt for NodeJs
Bruteshark2,601
3 months ago27gpl-3.0C#
Network Analysis Tool
Password_compat2,14015,3083093 years ago5November 20, 201419mitPHP
Compatibility with the password_* functions that ship with PHP 5.5
Rodauth1,4171593 days ago54June 22, 2022mitRuby
Ruby's Most Advanced Authentication Framework
Icebreaker1,147
4 years ago9mitPowerShell
Gets plaintext Active Directory credentials if you're on the internal network but outside the AD environment
Server1,103
2 days ago139gpl-3.0PHP
Hashtopolis - A Hashcat wrapper for distributed hashcracking
Redsnarf1,075
3 years ago5apache-2.0PowerShell
RedSnarf is a pen-testing / red-teaming tool for Windows environments
Hashid9591152 years ago2March 09, 201523Python
Software to identify the different types of hashes -
Naive Hashcat865
a year ago10mitC
Crack password hashes without the fuss :cat2:
Alternatives To Secure Password
Select To Compare


Alternative Project Comparisons
Readme

secure-password

Build Status Build status

Making Password storage safer for all

Features

  • State of the art password hashing algorithm (Argon2id)
  • Safe defaults for most applications
  • Future-proof so work factors and hashing algorithms can be easily upgraded
  • Buffers everywhere for safer memory management

Usage

var securePassword = require('secure-password')

// Initialise our password policy
var pwd = securePassword()

var userPassword = Buffer.from('my secret password')

// Register user
pwd.hash(userPassword, function (err, hash) {
  if (err) throw err

  // Save hash somewhere
  pwd.verify(userPassword, hash, function (err, result) {
    if (err) throw err
    
    switch (result) {
      case securePassword.INVALID_UNRECOGNIZED_HASH:
        return console.error('This hash was not made with secure-password. Attempt legacy algorithm')
      case securePassword.INVALID:
        return console.log('Invalid password')
      case securePassword.VALID:
        return console.log('Authenticated')
      case securePassword.VALID_NEEDS_REHASH:
        console.log('Yay you made it, wait for us to improve your safety')

        pwd.hash(userPassword, function (err, improvedHash) {
          if (err) console.error('You are authenticated, but we could not improve your safety this time around')

          // Save improvedHash somewhere
        })
        break
    }
  })
})

or with async await:

const securePassword = require('secure-password')

// Initialise our password policy
const pwd = securePassword()

const userPassword = Buffer.from('my secret password')

async function run () {
  // Register user
  const hash = await pwd.hash(userPassword)

  // Save hash somewhere
  const result = await pwd.verify(userPassword, hash)
  
  switch (result) {
    case securePassword.INVALID_UNRECOGNIZED_HASH:
      return console.error('This hash was not made with secure-password. Attempt legacy algorithm')
    case securePassword.INVALID:
      return console.log('Invalid password')
    case securePassword.VALID:
      return console.log('Authenticated')
    case securePassword.VALID_NEEDS_REHASH:
      console.log('Yay you made it, wait for us to improve your safety')

      try {
        const improvedHash = await pwd.hash(userPassword)
        // Save improvedHash somewhere
      } catch (err) {
        console.error('You are authenticated, but we could not improve your safety this time around')
      }
      break
  }
}

run()

API

var pwd = new SecurePassword(opts)

Make a new instance of SecurePassword which will contain your settings. You can view this as a password policy for your application. opts takes the following keys:

// Initialise our password policy (these are the defaults)
var pwd = securePassword({
  memlimit: securePassword.MEMLIMIT_DEFAULT,
  opslimit: securePassword.OPSLIMIT_DEFAULT
})

They're both constrained by the constants SecurePassword.MEMLIMIT_MIN - SecurePassword.MEMLIMIT_MAX and SecurePassword.OPSLIMIT_MIN - SecurePassword.OPSLIMIT_MAX. If not provided they will be given the default values SecurePassword.MEMLIMIT_DEFAULT and SecurePassword.OPSLIMIT_DEFAULT which should be fast enough for a general purpose web server without your users noticing too much of a load time. However your should set these as high as possible to make any kind of cracking as costly as possible. A load time of 1s seems reasonable for login, so test various settings in your production environment.

The settings can be easily increased at a later time as hardware most likely improves (Moore's law) and adversaries therefore get more powerful. If a hash is attempted verified with weaker parameters than your current settings, you get a special return code signalling that you need to rehash the plaintext password according to the updated policy. In contrast to other modules, this module will not increase these settings automatically as this can have ill effects on services that are not carefully monitored.

pwd.hash(password, [function (err, hash) {}])

Takes Buffer password and hashes it. You can call cancel to abort the hashing.

The hashing is done by a seperate worker as to not block the event loop, so normal execution and I/O can continue. The callback is invoked with a potential error, or the Buffer hash.

  • password must be a Buffer of length SecurePassword.PASSWORD_BYTES_MIN - SecurePassword.PASSWORD_BYTES_MAX.
  • hash will be a Buffer of length SecurePassword.HASH_BYTES.

If a callback is not specified, a Promise is returned.

var hash = pwd.hashSync(password)

Takes Buffer password and hashes it. The hashing is done on the same thread as the event loop, therefore normal execution and I/O will be blocked. The function may throw a potential error, but most likely return the Buffer hash.

password must be a Buffer of length SecurePassword.PASSWORD_BYTES_MIN - SecurePassword.PASSWORD_BYTES_MAX.
hash will be a Buffer of length SecurePassword.HASH_BYTES.

pwd.verify(password, hash, [function (err, enum) {}])

Takes Buffer password and hashes it and then safely compares it to the Buffer hash. The hashing is done by a seperate worker as to not block the event loop, so normal execution and I/O can continue. The callback is invoked with a potential error, or one of the symbols SecurePassword.INVALID, SecurePassword.VALID, SecurePassword.NEEDS_REHASH or SecurePassword.INVALID_UNRECOGNIZED_HASH. Check with strict equality for one the cases as in the example above.

If enum === SecurePassword.NEEDS_REHASH you should call pwd.hash with password and save the new hash for next time. Be careful not to introduce a bug where a user trying to login multiple times, successfully, in quick succession makes your server do unnecessary work.

password must be a Buffer of length SecurePassword.PASSWORD_BYTES_MIN - SecurePassword.PASSWORD_BYTES_MAX.
hash will be a Buffer of length SecurePassword.HASH_BYTES.

If a callback is not specified, a Promise is returned.

var enum = pwd.verifySync(password, hash)

Takes Buffer password and hashes it and then safely compares it to the Buffer hash. The hashing is done on the same thread as the event loop, therefore normal execution and I/O will be blocked. The function may throw a potential error, or return one of the symbols SecurePassword.VALID, SecurePassword.INVALID, SecurePassword.NEEDS_REHASH or SecurePassword.INVALID_UNRECOGNIZED_HASH. Check with strict equality for one the cases as in the example above.

SecurePassword.VALID

The password was verified and is valid

SecurePassword.INVALID

The password was invalid

SecurePassword.VALID_NEEDS_REHASH

The password was verified and is valid, but needs to be rehashed with new parameters

SecurePassword.INVALID_UNRECOGNIZED_HASH

The hash was unrecognized and therefore could not be verified. As an implementation detail it is currently very cheap to attempt verifying unrecognized hashes, since this only requires some lightweight pattern matching.

SecurePassword.HASH_BYTES

Size of the hash Buffer returned by hash and hashSync and used by verify and verifySync.

SecurePassword.PASSWORD_BYTES_MIN

Minimum length of the password Buffer.

SecurePassword.PASSWORD_BYTES_MAX

Maximum length of the password Buffer.

SecurePassword.MEMLIMIT_MIN

Minimum value for the opts.memlimit option.

SecurePassword.MEMLIMIT_MAX

Maximum value for the opts.memlimit option.

SecurePassword.OPSLIMIT_MIN

Minimum value for the opts.opslimit option.

SecurePassword.OPSLIMIT_MAX

Maximum value for the opts.opslimit option.

SecurePassword.MEMLIMIT_DEFAULT

Default value for the opts.memlimit option.

SecurePassword.OPSLIMIT_DEFAULT

Minimum value for the opts.opslimit option.

Install

npm install secure-password

Credits

I want to thank Tom Streller for donating the package name on npm. The <1.0.0 versions that he had written and published to npm can still be downloaded and the source is available in his scan/secure-password repository

License

ISC

Popular Password Projects
Popular Hash Projects
Popular Security Categories

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Javascript
Password
Hash
Hashing