Unified API for password hashing algorithms
npm install upash
π Unified API for PASsword Hashing algorithms
Coded with β€οΈ by Simone Primarosa.
Indeed, the above examples doubles as a list of "how NOT to do password
storage": simple hashing, unsalted values, misuse of encryption, and failed
password migration. (For more information on why these are bad, see our [introduction to password hashing theory][docs:password-hashing-theory])
There are two possible interpretations here: first, companies do not put adequate resources in securing passwords; and secondly, getting password hashing right is hard. Furthermore, even if you have followed previous best practice, keeping it right is another technical challenge: algorithm choices, security levels, parameter selection change regularly.

The upash ([pronounced u-pash][upash:pronounce]) project aims is to allow you to
have a clean and easy-to-use API to use any password hashing algorithm
seamlessly in your application.
*
#### Highlights
- Simple API for all password hashing algorithms
- Easy to maintain and upgradable logic
- Easy to test configurations through the CLI
- Step by step migration guide
- Comprehensive list of supported hashing algorithms
Do you believe that this is useful? Has it saved you time? Or maybe you simply like it?
If so, [support my work with a Star βοΈ][start].
Firstly, you need to install this package.
``bash`
npm install --save upash@phc/argon2
Then, you need to choose from the
list of supported password hashing algorithms
the one that best suits your needs and install that too.
In the following, we will assume that you choose , that is also a
suitable solution in case you don't know which one fits better for you.
`bash`
npm install --save @phc/argon2
Finally, you can enjoy the easy APIs.
`js
const upash = require('upash');
// Install the algorithm of your choice.
upash.install('argon2', require('@phc/argon2'));
// Hash API
const hashstr = await upash.hash('password');
// => "$argon2id$v=19$m=4096,t=3,p=1$PcEZHj1maR/+ZQynyJHWZg$2jEN4xcww7CYp1jakZB1rxbYsZ55XH2HgjYRtdZtubI"
// Verify API
const match = await upash.verify(hashstr, 'password');
// => true
`
You can store the hash returned by the hash function directly into your database.
You can also install more than one algorithm at once.
This is really handy when you want to update your current password hashing
algorithm.
`js
const upash = require('upash');
// Install the algorithms of your choice.
upash.install('pbkdf2', require('@phc/pbkdf2'));
upash.install('argon2', require('@phc/argon2'));
// You can explicitly tell upash which algorithm to use.
const hashstr_pbkdf2 = await upash.use('pbkdf2').hash('password');
// => "$pbkdf2-sha512$i=10000$O484sW7giRw+nt5WVnp15w$jEUMVZ9adB+63ko/8Dr9oB1jWdndpVVQ65xRlT+tA1GTKcJ7BWlTjdaiILzZAhIPEtgTImKvbgnu8TS/ZrjKgA"
// If you don't do so it will automatically use the last one installed.
const hashstr_argon2 = await upash.hash('password');
// => "$argon2i$v=19$m=4096,t=3,p=1$mTFYKhlcxmjS/v6Y8aEd5g$IKGY+vj0MdezVEKHQ9bvjpROoR5HPun5/AUCjQrHSIs"
// When you verify upash will automatically choose the algorithm to use based
// on the identifier contained in the hash string.
const match_pbkdf2 = await upash.verify(hashstr_pbkdf2, 'password');
// => true
// This will allow you to easily migrate from an algorithm to another.
const match_argon2 = await upash.verify(hashstr_argon2, 'password');
// => true
``
#### Packages that adhere to the PHC string format
- [@phc/argon2][alg:@phc/argon2]
- [@phc/pbkdf2][alg:@phc/pbkdf2]
- [@phc/scrypt][alg:@phc/scrypt]
- [@phc/bcrypt][alg:@phc/bcrypt]
#### Other packages
- N/A
Want your package listed here? [Open an issue][new issue] and we will review it.

Generally, each function allows configuration of 'work factorsβ.
Underlying mechanisms used to achieve irreversibility and govern work factors
(such as time, space, and parallelism) vary between functions.
You want to adjust the work factor to keep pace with threats' increasing hardware
capabilities so as to impede attackers while providing acceptable user experience
and scale.
A common rule of thumb for tuning the work factor (or cost) is to make the
function run as slow as possible without affecting the users' experience and
without increasing the need for extra hardware over budget.
The CLI lets you hash and verify password directly from your terminal.
You can use it to test work, memory and parallelism parameters on different
machines.
For installation and usage information about the CLI, see the
[upash-cli][gh:upash-cli] page.
Please if you do not find a migration documentation that fits your case,
[open an issue][new issue].
[This article][docs:ext:upgrade-algorithm] is a nice start that should give you
some ideas on what are the problems related to that process.
Example of implementations can be found in the
[upgrade algorithm guide][docs:upgrade-algorithm].
Installs a compatible password hashing function.
Uninstalls a password hashing function previously installed.
Array.<string>Gets the list of the installed password hashing functions.
ObjectSelects manually which password hashing function to use.
You can call hash and verify on the object returned.
string | nullReturns the name of the algorithm that has generated the hash string.
Promise.<boolean>Determines whether or not the hash provided matches the hash generated for
the given password choosing the right algorithm based on the identifier
contained in the hash.
Promise.<string>Computes the hash string of the given password using the 'last' algorithm
installed.
Kind: global function
Access: public
| Param | Type | Description |
| --- | --- | --- |
| name | string | The name of the password hashing function. |
| algorithm | Object | The password hashing function object. |
| algorithm.hash | function | A function that takes a password and returns a cryptographically secure password hash string. |
| algorithm.verify | function | A function that takes a secure password hash string and a password and returns whether or not the password is valid for the given hash string. |
| algorithm.identifiers | function | A function that returns the list of identifiers that this password hashing algorithm is able to generate / verify. |
Kind: global function
Access: public
| Param | Type | Description |
| --- | --- | --- |
| name | string | The name of the algorithm to uninstall or 'last' to uninstall the last one installed. |
Kind: global function
Returns: Array.<string> - The array of the available password hashing
functions.
Access: public
Kind: global function
Returns: Object - The password hashing function object.
Access: public
| Param | Type | Description |
| --- | --- | --- |
| name | string \| undefined | The name of the algorithm to use. |
Kind: global function
Returns: string \| null - The name of password hashing algorithm.
Access: public
| Param | Type | Description |
| --- | --- | --- |
| hashstr | string | Secure hash string generated from this package. |
Kind: global function
Returns: Promise.<boolean> - A boolean that is true if the hash computed
for the password matches.
Access: public
| Param | Type | Description |
| --- | --- | --- |
| hashstr | string | Secure hash string generated from this package. |
| password | string | User's password input. |
Kind: global function
Returns: Promise.<string> - The generated secure hash string.
Access: public
| Param | Type | Description |
| --- | --- | --- |
| password | string | The password to hash. |
| [options] | Object | Optional configurations related to the hashing function. See the algorithm specific documentation for the options supported. |
See also the list of [contributors][contributors] who participated in this project.
[start]: https://github.com/simonepri/upash#start-of-content
[new issue]: https://github.com/simonepri/upash/issues/new
[contributors]: https://github.com/simonepri/upash/contributors
[license]: https://github.com/simonepri/upash/tree/master/license
[gh:upash-cli]: https://github.com/simonepri/upash-cli
[alg:@phc/argon2]: https://github.com/simonepri/upash-argon2
[alg:@phc/scrypt]: https://github.com/simonepri/upash-scrypt
[alg:@phc/bcrypt]: https://github.com/simonepri/upash-bcrypt
[alg:@phc/pbkdf2]: https://github.com/simonepri/upash-pbkdf2
[github:simonepri]: https://github.com/simonepri
[twitter:simoneprimarosa]: http://twitter.com/intent/user?screen_name=simoneprimarosa
[argon2:password-competition]: https://password-hashing.net/
[upash:pronounce]: https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=en&q=u-pash
[docs:migration-guide]: https://github.com/simonepri/upash/tree/master/docs/migrate-your-solution.md
[docs:upgrade-algorithm]: https://github.com/simonepri/upash/tree/master/docs/upgrade-algorithm.md
[docs:password-hashing-theory]: https://github.com/simonepri/upash/tree/master/docs/password-hashing-theory.md
[docs:ext:upgrade-algorithm]: https://veggiespam.com/painless-password-hash-upgrades/
[breach:yahoo]: https://help.yahoo.com/kb/account/SLN27925.html
[breach:yahoo2]: https://help.yahoo.com/kb/account/sln28092.html
[breach:linkedin]: https://motherboard.vice.com/en_us/article/78kk4z/another-day-another-hack-117-million-linkedin-emails-and-password
[breach:adobe]: https://www.troyhunt.com/adobe-credentials-and-serious/
[breach:ashley-madison]: https://krebsonsecurity.com/2015/07/online-cheating-site-ashleymadison-hacked/
[breach:hibp-breaches]: https://haveibeenpwned.com/PwnedWebsites