hsh-cli 0.0.10

Command-line companion for the `hsh` password-hashing library: hash / verify / rehash / inspect / calibrate.
hsh-cli-0.0.10 is not a library.

Contents

Install · Quick Start · Subcommands · Password resolution · Exit codes · JSON output · Shell completions · Examples · Security


Install

cargo install hsh-cli

MSRV 1.85 stable. Edition 2024. Provides the hsh binary.

Packaging for Docker / Homebrew / Debian / Arch / Scoop is shipped under pkg/; each tagged release materialises ready-to-publish artefacts via release.yml.


Quick Start

# Hash a password (read from stdin)
echo -n "correct horse battery staple" | hsh hash
# → $argon2id$v=19$m=19456,t=2,p=1$<salt>$<hash>

# Verify
echo -n "correct horse battery staple" | hsh verify \
    -H '$argon2id$v=19$m=19456,t=2,p=1$<salt>$<hash>'
# → valid
# exit code 0

Subcommands

Command Purpose
hsh hash Hash a password → emit the storable PHC / MCF / envelope string
hsh verify Verify a candidate password against a stored hash
hsh rehash Verify + mint a fresh hash under the current policy (combined op)
hsh inspect Pretty-print the algorithm + parameters of any stored hash
hsh inspect-backend Show the effective crypto route for a preset (operator self-check)
hsh calibrate Walk a parameter ladder; report the params closest to a wall-time target
hsh completions Emit bash / zsh / fish / powershell / elvish completion scripts

Every subcommand accepts --json for machine-readable output. hash, verify, rehash, and inspect-backend take --policy {owasp,rfc9106,fips} to switch the parameter ladder; calibrate takes --algorithm and --target-ms instead.

hsh hash

hsh hash --algorithm argon2id --policy owasp
hsh hash --algorithm bcrypt   --policy owasp --json
hsh hash --algorithm pbkdf2   --policy fips         # errors: FIPS feature not built in

hsh verify

hsh verify -H "$STORED"
# Reads password from stdin / $HSH_PASSWORD env / TTY prompt.
# Plain output:
#   valid                          (exit 0)
#   needs_rehash: true             (when policy drifted)
#   rehashed: $argon2id$...        (the fresh hash to persist)
# Or:
#   invalid                        (exit 1)

hsh rehash

hsh rehash -H "$STORED" --policy rfc9106
# Verifies, then unconditionally mints a fresh hash under the
# current policy. Useful for batch migration scripts.

hsh inspect

hsh inspect '$argon2id$v=19$m=19456,t=2,p=1$YWJjZGVmZ2hpamtsbW5vcA$dGVzdA'
# → format:    phc
#   algorithm: argon2id
#   params[1]: v=19
#   params[2]: m=19456,t=2,p=1
#   segment[3]: YWJjZGVmZ2hpamtsbW5vcA
#   hash_b64:  dGVzdA

hsh inspect-backend

Operator self-check: confirms the binary's effective crypto route for a given preset before traffic touches it. Surfaces the backend (Native / Fips140Required), whether this build can satisfy a FIPS requirement (fips_available_in_build), the primary algorithm, whether the pepper feature was compiled in, plus build provenance (hsh-cli version, rustc, target triple, profile).

hsh --json inspect-backend --policy fips
# → {
#     "backend": "Fips140Required",
#     "fips_available_in_build": false,
#     "primary_algorithm": "Pbkdf2",
#     "readiness": "unsatisfied (build cannot provide a FIPS-validated route)",
#     "preset": "fips_140_pbkdf2",
#     "rustc": "rustc 1.95.0 (…)",
#     "target_triple": "x86_64-unknown-linux-gnu",
#
#   }

Gate a deploy with jq:

hsh --json inspect-backend --policy "$DESIRED" \
  | jq -e '.readiness == "satisfied"' >/dev/null \
  || { echo "hsh backend not ready for $DESIRED" >&2; exit 1; }

See doc/OPERATIONS.md for the full pre-deployment workflow.

hsh calibrate

hsh calibrate --algorithm argon2id --target-ms 500
# Walks m_cost ∈ {4096, 8192, 19456, 32768, 65536, 131072},
# reports the params that hit closest to 500 ms.
# JSON mode (--json) also emits a `ladder` array with every candidate
# and a `runner` block with host_os / arch / target_triple / profile /
# rustc / hsh_cli_version so sizing decisions are tied to the host
# that produced them.

hsh completions

hsh completions bash > /etc/bash_completion.d/hsh
hsh completions zsh  > ~/.zsh/functions/_hsh
hsh completions fish > ~/.config/fish/completions/hsh.fish

Password resolution

hsh-cli resolves the password in this order (and never accepts it on the command line):

  1. --password <value> flag — discouraged; documented as insecure (leaves password in shell history).
  2. $HSH_PASSWORD env var — for batch scripts.
  3. TTY prompt with no echo — when stdin is a terminal.
  4. First line of stdin — for pipelines.

The same priority applies to --stored / $HSH_STORED for hash inputs.


Exit codes

Code Meaning
0 Success (verify match, hash produced, completions emitted, etc.)
1 Verify mismatch (wrong password) — only verify and rehash
2 Error (malformed input, missing flag, policy contradiction)

These are stable per doc/API-STABILITY.md.


JSON output

Every subcommand accepts --json:

echo -n "secret" | hsh hash --algorithm scrypt --json
# {
#   "stored": "$scrypt$ln=17,r=8,p=1$<salt>$<hash>",
#   "algorithm": "Scrypt"
# }

The JSON schema is stable per the stability contract — additive changes only.


Shell completions

hsh-cli ships completions for bash, zsh, fish, powershell, elvish via the completions subcommand. The Arch (PKGBUILD) and Homebrew templates wire these into standard locations automatically — see pkg/.


Examples

See crates/hsh-cli/examples/ for the runnable demo:

  • library_shape.rs — programmatic walk-through of what the hash and verify subcommands do under the hood, useful for embedding the same flow in your own binary rather than shelling out.

Run with cargo run -p hsh-cli --example library_shape.


Security

  • Passwords are never on argv. The --password flag exists but is documented insecure.
  • Verify exits 1 on mismatch, 2 on error — no ambiguity for shell-script callers.
  • TTY prompts use rpassword (no echo).
  • No telemetry, no network calls, no log files.

See SECURITY.md for the vulnerability reporting policy.


License

Dual-licensed under Apache 2.0 or MIT, at your option.