:key: Idiotproof golang password validation library inspired by Python's passlib

passlib for go

GoDoc Build Status

Python's passlib is quite an amazing library. I'm not sure there's a password library in existence with more thought put into it, or with more support for obscure password formats.

This is a skeleton of a port of passlib to Go. It dogmatically adopts the modular crypt format, which passlib has excellent documentation for.

Currently, it supports:

  • Argon2i
  • scrypt-sha256
  • sha512-crypt
  • sha256-crypt
  • bcrypt
  • passlib's bcrypt-sha256 variant
  • pbkdf2-sha512 (in passlib format)
  • pbkdf2-sha256 (in passlib format)
  • pbkdf2-sha1 (in passlib format)

By default, it will hash using scrypt-sha256 and verify existing hashes using any of these schemes.

Example Usage

There's a default context for ease of use. Most people need only concern themselves with the functions Hash and Verify:

// Hash a plaintext, UTF-8 password.
func Hash(password string) (hash string, err error)

// Verifies a plaintext, UTF-8 password using a previously derived hash.
// Returns non-nil err if verification fails.
//
// Also returns an upgraded password hash if the hash provided is
// deprecated.
func Verify(password, hash string) (newHash string, err error)

Here's a rough skeleton of typical usage.

import "gopkg.in/hlandau/passlib.v1"

func RegisterUser() {
  (...)

  password := get a (UTF-8, plaintext) password from somewhere

  hash, err := passlib.Hash(password)
  if err != nil {
    // couldn't hash password for some reason
    return
  }

  (store hash in database, etc.)
}

func CheckPassword() bool {
  password := get the password the user entered
  hash := the hash you stored from the call to Hash()

  newHash, err := passlib.Verify(password, hash)
  if err != nil {
    // incorrect password, malformed hash, etc.
    // either way, reject
    return false
  }

  // The context has decided, as per its policy, that
  // the hash which was used to validate the password
  // should be changed. It has upgraded the hash using
  // the verified password.
  if newHash != "" {
    (store newHash in database, replacing old hash)
  }

  return true
}

scrypt Modular Crypt Format

Since scrypt does not have a pre-existing modular crypt format standard, I made one. It's as follows:

$s2$N$r$p$salt$hash

...where N, r and p are the respective difficulty parameters to scrypt as positive decimal integers without leading zeroes, and salt and hash are base64-encoded binary strings. Note that the RFC 4648 base64 encoding is used (not the one used by sha256-crypt and sha512-crypt).

Licence

passlib is partially derived from Python's passlib and so maintains its BSD license.

© 2008-2012 Assurance Technologies LLC.  (Python passlib)  BSD License
© 2014 Hugo Landau <[email protected]>  BSD License
Comments
  • Add argon2 crypter

    Add argon2 crypter

    Adds an argon2 crypter and promote it as the default scheme.

    Argon2 is the winner of the password hashing competition and is now available in other languages: PHP, Javascript, Ruby etc.

    The crypter uses the pure go implementation of argon2 here: https://godoc.org/golang.org/x/crypto/argon2

    Closes #4

  • Password migration?

    Password migration?

    First of all, thanks for this package! No nonsense, works as expected, and easy to extend. 👍

    For an app I'm working on, I wrote a small wrapper for the phpass package (used to authenticate users after a migration from Wordpress). However I'd also love to be able to migrate those users to more secure password hashes transparently as they sign in. But at the moment, Verify() only returns new hashes computed with the same algorithm as the "old" one.

    So would it be possible to either:

    • add a global (per-context) flag to "force" upgrading old hashes to the first in the context schemes?
    • or add a DeprecatedSchemes field to the passlib context that contain schemes that can be used to check passwords, but which will always trigger an upgrade to one in the normal Schemes?

    IMO the latter would be nicer. It's also similar to what the Python passlib does. What do you think? (I'm interested in writing a patch myself to implement whichever you prefer...)

  • PBKDF2 salt length is only 16 bytes?

    PBKDF2 salt length is only 16 bytes?

    https://github.com/hlandau/passlib/blob/e15f3479e40ed750ffb95950915cde348fad9319/hash/pbkdf2/pbkdf2.go#L37

    A 15 year old book recommends at least 32 bytes: https://stackoverflow.com/a/9622855

    Even if you leave the salt length as-is, a code comment for SaltLength would be nice explaining the rationale.

    P.S. yesterday I coded up a super small https://github.com/function61/gokit/blob/master/storedpassword/ package. After writing it, I searched around and found your library. I got many improvements by studying this design (for example Verify() returns upgraded version automatically), and am considering on just ditching my own and using this.. only advantage my library has is that it's smaller and serialization is simpler by embedding the cost parameter in algorithm id.

  • Add pbkdf2 derivative support in line with Pythons PassLib standards.

    Add pbkdf2 derivative support in line with Pythons PassLib standards.

    Requires custom base64 encoding/decoding as per the ab64_* methods in Python's PassLib. Substitutes + for . in the encoded version and vice versa when decoding.

    Includes tests to verify comparability with Python generated hashes.

    Includes benchmarks to compare derivatives.

    Adds all deriviatives to default verify context.

    Update README.md to include new methods and create a standard list to make it easier to read. Also remove TODO item.

  • It should be possible to set DefaultSchemes using strings

    It should be possible to set DefaultSchemes using strings

    If you're building a piece of software that plugs in to existing systems, you need to be able to configure the set of hashes that passlib will use, since unless you're using passlib (or maybe the Python version of passlib) everywhere, the chances are that the set of hashes that are supported is smaller than that supported by passlib, and you don't want passlib "upgrading" to a hash that other system components don't support.

    It's possible, of course, to import all the sub-packages in passlib and build a DefaultSchemes array yourself, but really there should be functionality in passlib to allow you to pass in a list of string tokens that passlib then converts to abstract.Schemes itself.

  • Example of how to change the hashing scheme from user code

    Example of how to change the hashing scheme from user code

    Can you please provide a simple example of how to change the hashing scheme preference from the user code. I am trying to create a Context with different order but as soon as I import the hashing packages, I start getting duplicate exported symbol errors.

  • Metrics

    Metrics

    I almost decided to use this library (and contribute PBKDF2). Then I found dependency on your metrics library. I like metrics too, but I don't think that hard dependency inside library (as apposed to application) is a good thing. Please consider to remove it.

Related tags
EarlyBird is a sensitive data detection tool capable of scanning source code repositories for clear text password violations, PII, outdated cryptography methods, key files and more.
EarlyBird is a sensitive data detection tool capable of scanning source code repositories for clear text password violations, PII, outdated cryptography methods, key files and more.

EarlyBird is a sensitive data detection tool capable of scanning source code repositories for clear text password violations, PII, outdated cryptograp

Dec 10, 2022
Driftwood is a tool that can enable you to lookup whether a private key is used for things like TLS or as a GitHub SSH key for a user.
Driftwood is a tool that can enable you to lookup whether a private key is used for things like TLS or as a GitHub SSH key for a user.

Driftwood is a tool that can enable you to lookup whether a private key is used for things like TLS or as a GitHub SSH key for a user. Drift

Dec 29, 2022
A convenience library for generating, comparing and inspecting password hashes using the scrypt KDF in Go 🔑

simple-scrypt simple-scrypt provides a convenience wrapper around Go's existing scrypt package that makes it easier to securely derive strong keys ("h

Dec 22, 2022
Secure Remote Password library for Go

go-srp NOTE: This is a port of node-srp to Go. I recommend reading their README for general information about the use of SRP. Installation go get gith

Aug 8, 2022
GoLang script that checks for password leaks by sending email address to the BreachDirectory API
GoLang script that checks for password leaks by sending email address to the BreachDirectory API

GoLang script that checks for password leaks by sending email address to the BreachDirectory API

Feb 17, 2022
Password manager written in golang
Password manager written in golang

Go password manager Password manager written in golang. Dependencies: gpg golang

Dec 2, 2021
Argon2 password hashing for Golang

Argon2 This is simple pure Golang implementation for password hash using Argon2. Usage package main import ( "fmt" "github.com/prastuvwxyz/argon2"

Dec 6, 2021
An API for hashing password in PostgreSQL with Golang

hashing-password An API for hashing password in PostgreSQL with Golang Using PostgreSQL to store Encrypted string (can be passwords ideally) using Sal

Sep 1, 2022
A light package for generating and comparing password hashing with argon2 in Go

argon2-hashing argon2-hashing provides a light wrapper around Go's argon2 package. Argon2 was the winner of the Password Hashing Competition that make

Sep 27, 2022
Argon2 password hashing package for go with constant time hash comparison

argon2pw Argon2 password hashing package with constant time hash comparison Preface: Argon2 was selected as the winner of the Password Hashing Competi

Sep 27, 2022
Password generator written in Go

go-generate-password Password generator written in Go. Use as a library or as a CLI. Usage CLI go-generate-password can be used on the cli, just insta

Dec 19, 2022
Validate the Strength of a Password in Go
Validate the Strength of a Password in Go

go-password-validator Simple password validator using raw entropy values. Hit the project with a star if you find it useful ⭐ Supported by Qvault This

Jan 6, 2023
A simple Go script to brute force or parse a password-protected PKCS#12 (PFX/P12) file.
A simple Go script to brute force or parse a password-protected PKCS#12 (PFX/P12) file.

A simple Go script to brute force or parse a password-protected PKCS#12 (PFX/P12) file.

Oct 14, 2022
Not Yet Another Password Manager written in Go using libsodium

secrets Secure and simple passwords manager written in Go. It aims to be NYAPM (Not Yet Another Password Manager), but tries to be different from othe

May 30, 2022
password manager using age for encryption

page ====== password manager using age (https://age-encryption.org/) for encryption. encrypted secrets are files in the $PAGE_SECRETS/ directory that

May 30, 2022
Custom GPG pinentry program for macOS that allows using Touch ID for fetching the password from the macOS keychain.
Custom GPG pinentry program for macOS that allows using Touch ID for fetching the password from the macOS keychain.

pinentry-touchid Custom GPG pinentry program for macOS that allows using Touch ID for fetching the password from the macOS keychain. Macbook Pro devic

Jan 1, 2023
A Go Module to interact with Passbolt, a Open source Password Manager for Teams

go-passbolt A Go Module to interact with Passbolt, a Open source Password Manager for Teams This Module tries to Support the Latest Passbolt Community

Oct 29, 2022
ZipExec is a Proof-of-Concept (POC) tool to wrap binary-based tools into a password-protected zip file.
ZipExec is a Proof-of-Concept (POC) tool to wrap binary-based tools into a password-protected zip file.

ZipExec ZipExec is a Proof-of-Concept (POC) tool to wrap binary-based tools into a password-protected zip file. This zip file is then base64 encoded i

Dec 31, 2022