Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tlinden/valpass
Simple golang library to validate passwords
https://github.com/tlinden/valpass
Last synced: 17 days ago
JSON representation
Simple golang library to validate passwords
- Host: GitHub
- URL: https://github.com/tlinden/valpass
- Owner: TLINDEN
- License: bsd-3-clause
- Created: 2024-10-11T15:05:17.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2024-11-18T07:16:43.000Z (2 months ago)
- Last Synced: 2024-11-18T08:26:10.184Z (2 months ago)
- Language: Go
- Size: 1.08 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![Go Report Card](https://goreportcard.com/badge/github.com/tlinden/valpass)](https://goreportcard.com/report/github.com/tlinden/valpass)
[![Actions](https://github.com/tlinden/valpass/actions/workflows/ci.yaml/badge.svg)](https://github.com/tlinden/valpass/actions)
[![Go Coverage](https://github.com/tlinden/valpass/wiki/coverage.svg)](https://raw.githack.com/wiki/tlinden/valpass/coverage.html)
![GitHub License](https://img.shields.io/github/license/tlinden/valpass)
[![GoDoc](https://godoc.org/github.com/tlinden/valpass?status.svg)](https://godoc.org/github.com/tlinden/valpass)# valpass - a small golang module to verify passwords
## Background
A decade ago I designed an encryption algorithm
just for fun and to learn more about cryptography.
During development I wrote a little helper tool
which I could use to verify some quality metrics
of my algorithm:
[analyze.c](https://github.com/TLINDEN/twenty4/blob/master/analyze/analyze.c).This module is a re-implementation of this code
with go as a reusable module.## Features
- standalone module without external dependencies
- uses 5 different metrics to measure password quality
- you can configure which metric to use
- you can also configure the quality thresholds
- there's support for dictionary lookup, but you need to provide the dictionary yourself
- it's reasonably fast
- the code is small enough to just copy it into your code## Quality metrics
![1000006662](https://github.com/user-attachments/assets/6cf19c6f-7c7a-4a2c-9a58-95b3ac1c49e7)
A good password is easy to remember and hard
to guess. Don't be fooled by those "use special characters"
evangelists: diceware passwords as outlined in the
well known xkcd comic are by far the best ones.However, if it's your job to implement a registration
user interface, then sooner or later you'll need
to validate passwords.This module can be used for this job.
By default it checks 3 metrics:
### Entropy
Entropy in this case measures the cryptographic
strength of the password. In non-technical words:
it checks how scrambled the password looks or how
many different bits it uses.We only look for printable US-ASCII characters.
### Character diffusion
Of course just measuring entropy is insufficient. For
instance a password `12345678` consists of 8 different
characters and might pass the entropy check. However, as
can be easily seen, the characters are sorted and
therefore this password would be a terrible one.Thus, character diffusion measures how characters are
distributed.Keep in mind that these two metrics would flag
the `Tr0ub4dor&3` password of the comic as pretty good,
while in reality it's not! You might remedy
this problem with a longer mandatory password
length. But the harsh reality is that people still
use such passwords.### Compression
We go one step further and also measure how much
the password can be compressed. For instance, let's
look at this run length encoding example:The string `aaabggthhhh` can be rle encoded to
`2ab2gt4h`. The result is shorter than the original, it is compressed.
The ideal password cannot be compressed
or not much.Of course we do not use RLE. We measure compression
using the [Flate algorithm](
https://en.m.wikipedia.org/wiki/Deflate).### Optional: dictionary check
You can supply a dictionary of words of your
liking and check if the password under test
matches one of the words. Submatches can also
be done.### Custom measurements
You can also enable or disable certain metrics and
you can tune the quality thresholds as needed.### Future/ ToDo
- checksum test using supplied checksum list, e.g. of leaked passwords
- fuzzy testing against dictionary to catch variations, using
Levenshtein or something similar.## Usage
Usage is pretty simple:
```go
import "github.com/tlinden/valpass"[..]
res, err := valpass.Validate("password"); if err != nil {
log.Fatal(err)
}
if !res.Ok {
log.Fatal("Password is unsecure!")
}
[..]
```You may also tune which tests you want to execute and with wich
parameters. To do this, just supply a second argument, which must be a
`valpas.Options` struct:```go
type Options struct {
Compress int // minimum compression rate in percent, default 10%
CharDistribution float64 // minimum character distribution in percent, default 10%
Entropy float64 // minimum entropy value in bits/char, default 3 bits/s
Dictionary *Dictionary // lookup given dictionary, the caller has to provide it
}
```To turn off a test, just set the tunable to zero.
Please take a look at [the
example](https://github.com/TLINDEN/valpass/blob/main/example/test.go)
or at [the unit tests](https://github.com/TLINDEN/valpass/blob/main/lib_test.go).## Performance
Benchmark results of version 0.0.1:
```default
% go test -bench=. -count 5
goos: linux
goarch: amd64
pkg: github.com/tlinden/valpass
cpu: Intel(R) Core(TM) i7-10610U CPU @ 1.80GHz
BenchmarkValidateEntropy-8 98703 12402 ns/op
BenchmarkValidateEntropy-8 92745 12258 ns/op
BenchmarkValidateEntropy-8 94020 12495 ns/op
BenchmarkValidateEntropy-8 96747 12349 ns/op
BenchmarkValidateEntropy-8 94790 12368 ns/op
BenchmarkValidateCharDist-8 95610 12184 ns/op
BenchmarkValidateCharDist-8 96631 12305 ns/op
BenchmarkValidateCharDist-8 97537 12215 ns/op
BenchmarkValidateCharDist-8 97544 13703 ns/op
BenchmarkValidateCharDist-8 95139 15392 ns/op
BenchmarkValidateCompress-8 2140 636274 ns/op
BenchmarkValidateCompress-8 5883 204162 ns/op
BenchmarkValidateCompress-8 5341 229536 ns/op
BenchmarkValidateCompress-8 4590 221610 ns/op
BenchmarkValidateCompress-8 5889 186709 ns/op
BenchmarkValidateDict-8 81 13730450 ns/op
BenchmarkValidateDict-8 78 16081013 ns/op
BenchmarkValidateDict-8 74 17545981 ns/op
BenchmarkValidateDict-8 92 12830625 ns/op
BenchmarkValidateDict-8 94 12564205 ns/op
BenchmarkValidateAll-8 5084 200770 ns/op
BenchmarkValidateAll-8 6054 193329 ns/op
BenchmarkValidateAll-8 5998 186064 ns/op
BenchmarkValidateAll-8 5996 191017 ns/op
BenchmarkValidateAll-8 6268 173846 ns/op
BenchmarkValidateAllwDict-8 374 3054042 ns/op
BenchmarkValidateAllwDict-8 390 3109049 ns/op
BenchmarkValidateAllwDict-8 404 3022698 ns/op
BenchmarkValidateAllwDict-8 393 3075163 ns/op
BenchmarkValidateAllwDict-8 381 3112361 ns/op
PASS
ok github.com/tlinden/valpass 54.017s
```## License
This module is licensed under the BSD license.
## Prior art
[go-password](https://github.com/wagslane/go-password-validator) provides similar
functionality and it's stable and battle tested.
However ir only measures the character entropy.