SiriusStarr / elm-password-strength / Zxcvbn

PasswordStrength.Zxcvbn is a native Elm implementation of the popular zxcvbn password strength javascript library. You likely want to use ZxcvbnPlus instead, unless you require exactly identical results to the reference implementation. More information may be found on its GitHub. The following is excerpted from the README:

zxcvbn is a password strength estimator inspired by password crackers. Through pattern matching and conservative estimation, it recognizes and weighs 30k common passwords, common names and surnames according to US census data, popular English words from Wikipedia and US television and movies, and other common patterns like dates, repeats ("aaa"), sequences ("abcd"), keyboard patterns ("qwertyuiop"), and l33t speak.

Consider using zxcvbn as an algorithmic alternative to password composition policy — it is more secure, flexible, and usable when sites require a minimal complexity score in place of annoying rules like "passwords must contain three of {lower, upper, numbers, symbols}".

Usage Notes

The results returned by this package should in all cases be exactly identical to those returned by the reference (javascript) implementation, with two exceptions. Firstly, this has updated the recent year regex to include the new decade (as the reference implementation only checked up to 201*). Secondly, exceedingly difficult to crack passwords may differ; as Elm lacks Number.MAX_VALUE, a value of 1.7976931348623157e+308 is used instead, which may differ slightly from Number.MAX_VALUE. If you do not require exactly identical results, consider using ZxcvbnPlus instead, which is a slightly more optimized and "Elm"-y implementation.

The computational performance of this library is quite good, with essentially instantaneous results for normal length passwords and barely perceptible delays even with ~100-character passwords.

It should be noted that the zxcvbn library is not "light" by any means, given the large dictionaries of common words it requires. Sizes for an extremely simple example application follow:

Known Issues

With exceedingly difficult to crack passwords, the algorithm may report bruteforce matches as "more guessable" than actual matches in the password. This is because the number of possible guesses for bruteforce caps at approximately 10^308 guesses. Since this is truly absurdly large, it should never be problematic in normal use.

Functions

This package exposes exactly one function, zxcvbn, which requires no configuration of any kind and may be simply called with a password (and possible-empty list of additional patterns).

zxcvbn : List String -> String -> ZxcvbnResult

zxcvbn takes two arguments, a List String of user patterns and a String password, and returns a result record of type ZxcvbnResult.

The user patterns argument (which may be an empty list) is an array of strings that zxcvbn will treat as an extra dictionary. This can be whatever list of strings you like but is meant for user inputs from other fields of the form, like name and email. That way a password that includes a user's personal information can be heavily penalized. This list is also good for site-specific vocabulary -- Acme Brick Co. might want to include ["acme", "brick", "acmebrick", etc]. This list is ordered in increasing rank, which the first element of the list being the highest rank (most common). Entries with higher ranks are more strongly penalized. However, unless a truly massive list is used, the ordering is unlikely to be relevant. User patterns are not case-sensitive.

Result Types

The sole function in this package returns one relatively complex record containing the full results of the password strength check.


type alias ZxcvbnResult =
{ score : Basics.Int
, feedback : Feedback
, crackTimesDisplay : DisplayCrackTimes
, crackTimesSeconds : NumericCrackTimes
, guesses : Basics.Int
, guessesLog10 : Basics.Float
, password : String
, sequence : List MatchTypes.ScoredMatch 
}

ZxcvbnResult is returned by zxcvbn and holds the results of the password strength check. It has the following fields:


type alias Feedback =
{ warning : String
, suggestions : List String 
}

Contains feedback inteded to be displayed to the user trying to create a password.


type alias DisplayCrackTimes =
{ onlineThrottling100PerHour : String
, onlineNoThrottling10PerSecond : String
, offlineSlowHashing1e4PerSecond : String
, offlineFastHashing1e10PerSecond : String 
}

Crack times for password in user-friendly format (e.g. "less than a second", "10 years", etc.) for various cases.


type alias NumericCrackTimes =
{ onlineThrottling100PerHour : Basics.Float
, onlineNoThrottling10PerSecond : Basics.Float
, offlineSlowHashing1e4PerSecond : Basics.Float
, offlineFastHashing1e10PerSecond : Basics.Float 
}

Crack times for password in seconds for various cases.