Files
2026-05-27 23:47:53 +01:00

106 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# @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.
<!-- begin:auto-docs -->
## Documentation tree
- [bin](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
<!-- end:auto-docs --> - [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/bin/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_- [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_ - [hash-password](./src/hash-password/hash-password.md) — <!-- begin:auto-docs --> _(no submodules)_
## Quickstart
```bash
# 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
```ts
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 (throws `HashPasswordCliError`).
- `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` — `SuaveplanError` base + 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.