Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Hash Wasm | 563 | 104 | 21 days ago | 38 | November 13, 2023 | 8 | other | TypeScript | ||
Lightning fast hash functions using hand-tuned WebAssembly binaries | ||||||||||
Noble Hashes | 372 | 697 | 17 days ago | 27 | August 23, 2023 | 3 | mit | JavaScript | ||
Audited & minimal JS implementation of hash functions, MACs and KDFs. | ||||||||||
Node Scrypt | 356 | 4,363 | 166 | 4 years ago | 46 | May 01, 2016 | 59 | C | ||
Scrypt for Node | ||||||||||
Password4j | 292 | 4 | 3 months ago | 21 | September 14, 2023 | 5 | apache-2.0 | Java | ||
Java cryptographic library that supports Argon2, bcrypt, scrypt and PBKDF2 aimed to protect passwords in databases. Easy to use by design, highly customizable, secure and portable. All the implementations follow the standards and have been reviewed to perform better in the JVM. | ||||||||||
Genesish0 | 218 | 6 years ago | 21 | apache-2.0 | Python | |||||
SHA256/scrypt/X11/X13/X15 genesis blocks for virtual currencies | ||||||||||
Argon2_elixir | 209 | 158 | 19 | 2 months ago | 48 | October 09, 2023 | 4 | apache-2.0 | Elixir | |
Elixir wrapper for the Argon2 password hashing algorithm | ||||||||||
Simple Scrypt | 164 | 38 | 71 | 4 years ago | 3 | April 12, 2021 | 2 | mit | Go | |
A convenience library for generating, comparing and inspecting password hashes using the scrypt KDF in Go 🔑 | ||||||||||
Webscrypt | 136 | 6 years ago | 1 | JavaScript | ||||||
a fast and lightweight scrypt hash algorithm for browser | ||||||||||
Scrypt | 84 | 7 | 11 | 4 years ago | 5 | February 08, 2017 | 1 | apache-2.0 | C# | |
A .NET implementation of scrypt password hash algorithm. | ||||||||||
Yescrypt | 83 | 2 months ago | 1 | C | ||||||
Password-based key derivation function and password hashing scheme building upon scrypt |
simple-scrypt provides a convenience wrapper around Go's existing scrypt package that makes it easier to securely derive strong keys ("hash user passwords"). This library allows you to:
The API closely mirrors Go's bcrypt library in an effort to make it easy to migrate—and because it's an easy to grok API.
With a working Go toolchain:
go get -u github.com/elithrar/simple-scrypt
simple-scrypt doesn't try to re-invent the wheel or do anything "special". It
wraps the scrypt.Key
function as thinly as possible, generates a
crytographically secure salt for you using Go's crypto/rand
package, and
returns the derived key with the parameters prepended:
package main
import(
"fmt"
"log"
"github.com/elithrar/simple-scrypt"
)
func main() {
// e.g. r.PostFormValue("password")
passwordFromForm := "prew8fid9hick6c"
// Generates a derived key of the form "N$r$p$salt$dk" where N, r and p are defined as per
// Colin Percival's scrypt paper: http://www.tarsnap.com/scrypt/scrypt.pdf
// scrypt.Defaults (N=16384, r=8, p=1) makes it easy to provide these parameters, and
// (should you wish) provide your own values via the scrypt.Params type.
hash, err := scrypt.GenerateFromPassword([]byte(passwordFromForm), scrypt.DefaultParams)
if err != nil {
log.Fatal(err)
}
// Print the derived key with its parameters prepended.
fmt.Printf("%s\n", hash)
// Uses the parameters from the existing derived key. Return an error if they don't match.
err := scrypt.CompareHashAndPassword(hash, []byte(passwordFromForm))
if err != nil {
log.Fatal(err)
}
}
Upgrading derived keys from a set of parameters to a "stronger" set of parameters as hardware improves, or as you scale (and move your auth process to separate hardware), can be pretty useful. Here's how to do it with simple-scrypt:
func main() {
// SCENE: We've successfully authenticated a user, compared their submitted
// (cleartext) password against the derived key stored in our database, and
// now want to upgrade the parameters (more rounds, more parallelism) to
// reflect some shiny new hardware we just purchased. As the user is logging
// in, we can retrieve the parameters used to generate their key, and if
// they don't match our "new" parameters, we can re-generate the key while
// we still have the cleartext password in memory
// (e.g. before the HTTP request ends).
current, err := scrypt.Cost(hash)
if err != nil {
log.Fatal(err)
}
// Now to check them against our own Params struct (e.g. using reflect.DeepEquals)
// and determine whether we want to generate a new key with our "upgraded" parameters.
slower := scrypt.Params{
N: 32768,
R: 8,
P: 2,
SaltLen: 16,
DKLen: 32,
}
if !reflect.DeepEqual(current, slower) {
// Re-generate the key with the slower parameters
// here using scrypt.GenerateFromPassword
}
}
Thanks to the work by tgulacsi, you can have simple-scrypt automatically determine the optimal parameters for you (time vs. memory). You should run this once on program startup, as calibrating parameters can be an expensive operation.
var params scrypt.Params
func main() {
var err error
// 500ms, 64MB of RAM per hash.
params, err = scrypt.Calibrate(500*time.Millisecond, 64, Params{})
if err != nil {
return nil, err
}
...
}
func RegisterUserHandler(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Make sure you validate: not empty, not too long, etc.
email := r.PostFormValue("email")
pass := r.PostFormValue("password")
// Use our calibrated parameters
hash, err := scrypt.GenerateFromPassword([]byte(pass), params)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Save to DB, etc.
}
Be aware that increasing these, whilst making it harder to brute-force the resulting hash, also increases the risk of a denial-of-service attack against your server. A surge in authenticate attempts (even if legitimate!) could consume all available resources.
MIT Licensed. See LICENSE file for details.