pwhaas1.2.0 • Public • Published
Pwhaas is a service that lets the good guys hash passwords with the same powerful hardware used by attackers. This makes the attacker's job 100's of times harder as it increases the amount of time they have to spend guessing the passwords.
This service offloads CPU intensive password hashing from your application servers so they can do what they are good at and asynchronously wait on IO instead.
It hashes passwords with the latest recommended salt generating and memory-hard algorithm optimized for x86: (Argon2). It is designed to hash in parallel on high CPU count systems with up to 4GB of memory utilized in order to make the resulting hashes difficult to crack with GPUs or ASIC processors.
By default this module will connect to api.pwhaas.com and hash on a VM with 8 CPU cores. It will hash for 1,000ms. For free. For higher security hashes utilizing 10's of CPU cores in parallel, and higher performance servers running on metal (no VM) you'll have to sign up for an account.
This module makes it easy to use the pwhaas service with the same interface you would use to hash passwords locally.
Pwhaas is resilient. If the pwhaas service is unavailable this module utilizes argon2themax to find an expensive set of hash options and will compute the hash locally.
Your users' passwords are hashed with argon2 locally before sending them to the pwhaas service. This helps protect them even if there is a MITM attack or the pwhaas service itself is hacked.
pwhaas depends on the argon2 Node module, which
requires node-gyp to be installed globally. It also requires a modern
C++ compiler. Please see the argon2 ReadMe
for more information if you have trouble running
We require Node.JS v4.0.0+.
npm install -g node-gypnpm install --save pwhaas
Set options with environment variables
You can set the options via environment variables. Remember to keep your API Key private and don't commit it to any public repos.
# Your API Key... The default will let you hash in a free trial mode, with less secure hashes.export PWHAAS_API_KEY='[Your API Key Here]'# The amount of time (ms) you want the service to spend hashing per passwordexport PWHAAS_MAX_TIME=250# The URI to the API server. You shouldn't need to set this unless you are self hosting.export PWHAAS_ROOT_URI=''# The amount of time to give the API (ms) before falling back to a local hashexport PWHAAS_API_TIMEOUT=5000
Set options via code
setOptions function or when you make your call to
Remember to keep your API Key private and don't commit it to any public repos. Yes, I repeated myself. :)
pwhaas;// OR....await pwhaas;
Use the service
// TypeScript / ES7;const plain = "password";// Init the service once before using it.// This will find some secure hash options to use for local hashing in case pwhaas is unreachable.await pwhaas;// Hashing happens in an asynchronous event using libuv so your system can// still process other IO items in the Node.JS queue, such as web requests.const hashResponse = await pwhaashashplain;// This hash is what you should store in your database. Treat it as an opaque string.// The response also contains information on how long the hashing took, the// Argon2 options that were used, and whether or not we had to fall back to hashing locally.console;// Verifying the hash against your user's password is simple.const verifyResponse = await pwhaas;console;
You can also specify your api key and the service root uri when you
init your pwhaas service.
The defaults global options are:
When you call
hash you can specify the amount of time you would like pwhaas to
spend hashing. The service will choose options that will take close to that compute
time. By default it uses the
maxtime specified during
init. The service allows
you to utilize up to 1,000ms of compute time.
// This would be a very secure hash...const hashResponse = await pwhaashash"password" 1000;
If you want multiple instances of pwhaas with different configurations you can do that as well. You can just instantiate the Pwhaas class and use it as shown in the examples above that utilize the singleton.
;// You can specify options on the constructor of this classconst pwhaas = apiKey: "[Your API Key Here]" ;const maxLocalOptions = await pwhaas;
var Pwhaas = Pwhaas;var pwhaas = ;// You can also specify options on the init() functionpwhaas;