5.2 KiB
@suaveplan/crypto-bin - Suaveplan crypto bins: suaveplan-hash-password (Argon2id / blake2b password hash + verify CLI). Lives in its own package so the universal @suaveplan/crypto does not pull in @suaveplan/cli runtime deps.
Summary
Suaveplan password-hashing CLI. Ships the suaveplan-hash-password
binary — Argon2id (default) and BLAKE2b password hashing + verification
with PHC/MCF-formatted output strings, distinct exit codes per failure
class, and an env-injected output adapter so the core is testable
without subprocess spawn.
This package lives separately from @suaveplan/crypto so the
universal crypto façade does not pull CLI runtime deps into
browser/server consumers that just want primitives.
Documentation tree
- bin — (no submodules)
- hash-password — (no submodules)
- hash-password — (no submodules)
- hash-password — (no submodules)
Quickstart
# Hash a password (Argon2id by default)
$ suaveplan-hash-password --password "correct horse battery staple"
$argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>
# Verify (exit 0 = match, 1 = mismatch)
$ suaveplan-hash-password --password "correct horse battery staple" \
--verify '$argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>'
$ echo $?
0
Algorithms
--algo argon2id(default) — OWASP 2023-recommended password hash. Output prefix$argon2id$v=19$....--algo blake2b— opt-in alternative for environments that need it. Output prefix$blake2b$v=1$.... Cost factor is configurable via--cost-factor <n>(1–31).
The verify mode auto-detects the algorithm from the stored hash's prefix, so callers do not have to track which algorithm was used at hash time.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success / verify matched |
| 1 | Verify mismatch (wrong password) |
| 2 | Bad arguments (missing/malformed flag value) |
| 3 | Unknown algorithm (unrecognised --algo or stored prefix) |
| 4 | Verify failed (stored hash is corrupt or unparseable) |
The 0 / 1 split matches the de-facto contract for shell pipelines —
if suaveplan-hash-password --password ... --verify ...; then ...; fi
works as expected, with 3+ reserved for operator errors so callers can
distinguish "wrong password" from "stored data is broken".
Programmatic use
import { main } from "@suaveplan/crypto-bin";
const out: string[] = [];
const err: string[] = [];
const code = main(
["--password", "pw", "--algo", "blake2b", "--cost-factor", "10"],
{
write: (s) => out.push(s),
writeError: (s) => err.push(s),
},
);
if (code === 0) {
storeHash(out.join("").trim());
}
The main() function never throws — every error path is captured and
surfaced via env.writeError(...) and a non-zero return value. See
src/hash-password/hash-password.md for the full contract.
Public surface
main— testable CLI core.parseArgs— pure argv parser (throwsHashPasswordCliError).detectAlgo— algorithm sniffer for stored hashes.HashPasswordCliEnv— output adapter interface.HashPasswordCliError— error class wrapping the stable code registry.HASH_PASSWORD_CLI_CODES—BAD_ARGS/UNKNOWN_ALGO/VERIFY_FAILED.
Dependencies
@suaveplan/crypto-hash— Argon2id + BLAKE2b primitives.@suaveplan/error—SuaveplanErrorbase + stable code registry.@suaveplan/types— shared cross-package contracts.
No dependency on @suaveplan/cli — argv parsing is hand-rolled (~40
lines) so the bin stays small.