Previous: , Up: API  


1.4 (bewaking password)

1.4.1 Procedures

Procedure: generate-strong-password KEY: #:length #:include-symbols

Generate a random password designed to be strong.

One character from each included class is guaranteed, the remainder is drawn from the full pool, and the result is shuffled so no positional bias remains.

#:key length: total password length (default 24). Must be at least as large as the number of included character classes. #:key include-symbols: when #t (default) symbols are part of the pool. #:returns: a freshly generated password string.

#:example (generate-strong-password) ; 24 chars, mixed classes (generate-strong-password #:length 32) (generate-strong-password #:length 16 #:include-symbols #f)

Procedure: hash-password KEY: #:password #:memory-kib #:iterations #:parallelism

Hash password with Argon2id and return a PHC string such as $argon2id$v=19$m=65536,t=3,p=1$...$....

A fresh 16-byte salt is drawn from the CSPRNG for every call, so hashing the same password twice gives two different strings; the parameters are recorded in the string, so ‘verify-password‘ needs no configuration to check it later.

#:key memory-kib: Argon2id memory cost in kibibytes (default 65536). #:key iterations: Argon2id passes (default 3). #:key parallelism: Argon2id lanes (default 1).

#:example (hash-password #:password "correct horse battery staple")

Procedure: password-character-classes password

Return the list of character classes present in password.

The returned symbols are drawn from: lowercase, uppercase, digit and symbol. Anything that is not a letter, digit or whitespace is treated as a symbol, so punctuation, math symbols and other printable non-alphanumeric characters are covered.

#:example (password-character-classes "Abc123!") ; => (lowercase uppercase digit symbol)

The password is walked once, accumulating the four flags; the previous version scanned the whole password once per class, which made this the most expensive part of ‘password-strength‘ for long passphrases.

Procedure: password-entropy KEY: #:password

Return the raw estimated entropy of password in bits.

The estimate is length * log2(pool-size), where the pool size is the sum of the sizes of every character class present in the password. This is a simple model of guessing difficulty, not a guarantee of strength; use ‘password-strength‘ for a penalty-adjusted score.

#:example (password-entropy #:password "Tr0ub4dor&3") ; => a number of bits

Procedure: password-hash? value

Return #t when value is a well-formed Argon2id PHC hash string, as produced by ‘hash-password‘.

Procedure: password-strength KEY: #:password

Measure the strength of password and return an association list describing the result.

The estimate starts from ‘password-entropy‘, then applies penalties for common passwords, short lengths, repeated characters and sequential runs. A common password always scores 0.

The returned alist contains: - score: integer 0 (very weak) to 4 (very strong) - label: human-readable label for the score - entropy: penalty-adjusted entropy estimate, in bits - raw-entropy: unpenalized entropy estimate, in bits - length: length of the password - classes: character classes detected (list of symbols) - feedback: list of suggestions to improve the password

#:example (password-strength #:password "correct horse battery staple")

Procedure: password-strength-label score

Return a human-readable label for a numeric strength score between 0 and 4.

Procedure: strong-password? KEY: #:password #:min-score

Return #t when password scores at least min-score (default 3, "strong") according to ‘password-strength‘, otherwise #f.

#:example (strong-password? #:password "Tr0ub4dor&3") ; => #t or #f (strong-password? #:password "123456" #:min-score 4) ; => #f

Procedure: verify-password KEY: #:password #:hash #:max-memory-kib #:max-iterations

Return #t when password is the one hash was made from, and #f otherwise — including when hash is not a hash this library wrote.

The recorded cost is refused, not obeyed, when it is beyond max-memory-kib or max-iterations: a hash normally arrives from storage or from a client, and a 4 GiB memory cost would be a denial of service rather than a credential. The comparison itself is constant-time.

#:example (verify-password #:password attempt #:hash stored-hash)


Previous: (bewaking crypto), Up: API