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

Deploy Mentioned in Awesome Go

This project can be used to front a password strength meter, or simply validate password strength on the server. Benefits:

  • No stupid rules (doesn't require uppercase, numbers, special characters, etc)
  • Everything is based on entropy (raw cryptographic strength of the password)
  • Doesn't load large sets of data into memory - very fast and lightweight
  • Doesn't contact any API's or external systems
  • Inspired by this XKCD

XKCD Passwords

⚙️ Installation

Outside of a Go module:

go get github.com/lane-c-wagner/go-password-validator

🚀 Quick Start

package main

import (
    passwordvalidator "github.com/lane-c-wagner/go-password-validator"
)

func main(){
    entropy := passwordvalidator.GetEntropy("a longer password")
    // entropy is a float64, representing the strength in base 2 (bits)

    const minEntropyBits = 60
    err := passwordvalidator.Validate("some password", minEntropyBits)
    // if the password has enough entropy, err is nil
    // otherwise, a formatted error message is provided explaining
    // how to increase the strength of the password
    // (safe to show to the client)
}

What Entropy Value Should I Use?

It's up to you. That said, here is a graph that shows some common timings for different values, somewhere in the 50-70 range seems "reasonable".

Keep in mind that attackers likely aren't just brute-forcing passwords, if you want protection against common passwords or PWNed passwords you'll need to do additional work. This library is lightweight, doesn't load large datasets, and doesn't contact external services.

entropy

How It Works

First, we determine the "base" number. The base is a sum of the different "character sets" found in the password.

We've arbitrarily chosen the following character sets:

  • 26 lowercase letters
  • 26 uppercase letters
  • 10 digits
  • 5 replacement characters - !@$&*
  • 5 seperator characters - _-.,
  • 22 less common special characters - "#%'()+/:;<=>?[\]^{|}~

Using at least one character from each set your base number will be 94: 26+26+10+5+5+22 = 94

Every unique character that doesn't match one of those sets will add 1 to the base.

If you only use, for example, lowercase letters and numbers, your base will be 36: 26+10 = 36.

After we have calculated a base, the total number of brute-force-guesses is found using the following formulae: base^length

A password using base 26 with 7 characters would require 26^7, or 8031810176 guesses.

Once we know the number of guesses it would take, we can calculate the actual entropy in bits using log2(guesses). That calculation is done in log space in practice to avoid numeric overflow.

Additional Safety

We try to err on the side of reporting less entropy rather than more.

Same Character

With repeated characters like aaaaaaaaaaaaa, or 111222, we modify the length of the sequence to count as no more than 2.

  • aaaa has length 2
  • 111222 has length 4

Common Sequences

Common sequences of length three or greater count as length 2.

  • 12345 has length 2
  • 765432 has length 2
  • abc has length 2
  • qwerty has length 2

The sequences are checked from back->front and front->back. Here are the sequences we've implemented so far, and they're case-insensitive:

  • 0123456789
  • qwertyuiop
  • asdfghjkl
  • zxcvbnm
  • abcdefghijklmnopqrstuvwxyz

Not ZXCVBN

There's another project that has a similar purpose, zxcvbn, and you may want to check it out as well. Our goal is not to be zxcvbn, because it's already good at what it does. go-password-validator doesn't load any large datasets of real-world passwords, we write simple rules to calculate an entropy score. It's up to the user of this library to decide how to use that entropy score, and what scores constitute "secure enough" for their application.

💬 Contact

Twitter Follow

Submit an issue (above in the issues tab)

Transient Dependencies

None! And it will stay that way, except of course for the standard library.

👏 Contributing

I love help! Contribute by forking the repo and opening pull requests. Please ensure that your code passes the existing tests and linting, and write tests to test your changes if applicable.

All pull requests should be submitted to the main branch.

make test
make fmt
make vet
make lint
Owner
Comments
  • Add error to Validate if password is common

    Add error to Validate if password is common

    Inspired by how bad pattern locks are on phones, I added some code to count continuous (or maybe contiguous) pattern lengths as 0.

    If you swipe your finger across your keyboard, in any direction, along the red lines in this image, it will be length 0.

    Please let me know which changes you'd like to see and if these additions are appropriate. Disallowing patterns may count as one of those stupid rules. :smiley:

  • Adress issues raised by staticcheck and add it to workflow

    Adress issues raised by staticcheck and add it to workflow

    Staticcheck is a wonderful tool for performing static analysis of Go programs. This PR addresses all the issues (3 to be exact) that it mentioned and also adds it to the workflow for further checks in the future. I also updated the checkout action to v2 which most importantly has some performance work :)

  •  passwordvalidator.Validate always return nil error, even when the supplied password is well below min entropy

    passwordvalidator.Validate always return nil error, even when the supplied password is well below min entropy

    Describe the bug Validate method always returns nil error, even when password entropy is less than minimum entropy

    To Reproduce No additional steps required, it is a main line usecase. try with password as "123" with minimum entropy as 60 func strongPass(password string) error { const minEntropyBits = 60 err := passwordvalidator.Validate(password, minEntropyBits) return err }

    The problem is the following code, when you return error object it is nil to calling function, as the call fmt.Errorf it is by value and is lost on return.

    if len(allMessages) > 0 {
    	return fmt.Errorf(
    		"insecure password, try %v or using a longer password",
    		strings.Join(allMessages, ", "),
    	)
    }
    

    Expected behavior Should return an error.

    Screenshots None

    Environment (please complete the following information):

    • OS: Mac OSX

    Additional context None

  • 10001010101010101001110101010101010101010101010101010101 should be secure

    10001010101010101001110101010101010101010101010101010101 should be secure

    So the password 1010101010101011101101000000010111011011101001010001001101011011 is calculated as only having a length of "2" and a base of 10. So it would be about 6 bits according to this. But the generation method clearly is generating a binary string with length 64, for a total of 64 bits of entropy.

  • Passwords with fghijkl are reported as more secure than they are

    Passwords with fghijkl are reported as more secure than they are

    Describe the bug The getLength function is supposed to strip sequential characters after a run length of 2. e.g. fghijkl should become fg.

    However, because it first replaces the sequence asdfghjkl, it changes fghijkl to fgijk, which then becomes 'fgij, a length of 4.

    To Reproduce

    https://github.com/wagslane/go-password-validator/pull/14

    Expected behavior It should change fghijkl to fg

    Screenshots If applicable, add screenshots or console output that helps explain the situation

    Environment (please complete the following information):

    • OS: [e.g. Linux Ubuntu]

    Additional context Add any other context about the problem here.

  • Fix get length on strings containing fghijkl.

    Fix get length on strings containing fghijkl.

    The asdfghjkl sequence was running first, resulting in a sequence like fgijk, which then would turn into fgij, when it should have turned into fg. Running seqAlphabet first avoids this issue, but then asdfghjkl gets the same issue. To remedy, we can run both and then see which one removed more characters.

  • Allow configuration such as error messages and character sets

    Allow configuration such as error messages and character sets

    Is your feature request related to a problem? Please describe.

    I was looking around if we have any go packages to handle password strength validation and I stumbled upon this. I do like the idea behind this and I have a few suggestions that may come in handy:

    • Allow custom error messages or expand the validate function to provide analytical data which can be used to determine error messages outside of the package (the primary idea of this is to allow i18n).
    • Allow the validator to be configured with custom character sets or programmatically determine used character sets to support use cases that would require characters outside of the baked-in character sets.

    Describe the solution you'd like

    My first point should be straightforward on how it could be implemented; something in the lines of returning a struct which outlines the boolean flags used internally (hasReplace, hasLower, ...).

    For the second one, I am quite unsure on how (if even possible) to implement as changes to the character sets would affect the entropy and what level would be considered secure (the table in your README).

    Is this something you would consider your package to support? With your insight and if we decide to use this approach for Corteza, I can assist with the implementation.

go-opa-validate is an open-source lib that evaluates OPA (open policy agent) policy against JSON or YAML data.
go-opa-validate is an open-source lib that evaluates OPA (open policy agent) policy against JSON or YAML data.

go-opa-validate go-opa-validate is an open-source lib that evaluates OPA (open policy agent) policy against JSON or YAML data. Installation Usage Cont

Nov 17, 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
:key: Idiotproof golang password validation library inspired by Python's passlib

passlib for go 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 wi

Dec 30, 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
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
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
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
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
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
User enumeration and password bruteforce on Azure, ADFS, OWA, O365 and gather emails on Linkedin
User enumeration and password bruteforce on Azure, ADFS, OWA, O365 and gather emails on Linkedin

goEnumBruteSpray Description Summary The recommended module is o365 for user enumeration and passwords bruteforce / spray . Additional information can

Dec 25, 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
Simple password manager app in GO

Introduction This is my first project in Go, a password manager application. A humble attempt at execution of an idea I've had for some time now. The

Sep 13, 2022