Prints the current Steam Guard (TOTP) code for a shared secret.
The secret is the base64 shared_secret field from a Steam Desktop Authenticator
maFile.
cargo build --releaseThe binary lands at target/release/steamguard-cli.
steamguard-cli <SECRET> # secret as an argument
STEAM_SHARED_SECRET=<SECRET> steamguard-cli
echo <SECRET> | steamguard-cli # secret on stdinThe secret is read from the argument first, then $STEAM_SHARED_SECRET, then
stdin. Only the 5-character code goes to stdout, so it pipes cleanly:
CODE=$(steamguard-cli < ~/.steam-secret)| Option | Purpose |
|---|---|
-t, --time <UNIX_SECONDS> |
Generate the code for a specific Unix timestamp instead of now |
-r, --remaining |
Print how many seconds the code stays valid (on stderr) |
-h, --help / -V, --version |
Usage and version |
Exit code is 0 on success, 1 with a message on stderr otherwise.
Passing the secret as a command-line argument makes it visible to other users
via ps and leaves it in shell history. Prefer STEAM_SHARED_SECRET or stdin.
An empty secret is rejected rather than accepted: HMAC would happily take a zero-length key and print a plausible-looking but meaningless code. A secret that decodes to anything other than 20 bytes still produces a code, but prints a warning first, since that usually means a truncated paste.
Standard HOTP/TOTP (RFC 4226/6238) — HMAC-SHA1 over the 30-second counter, then
RFC 4226 dynamic truncation. Steam differs only at the last step: instead of
decimal digits, the truncated value is written in base 26 using the alphabet
23456789BCDFGHJKMNPQRTVWXY, which omits characters that are easy to misread.
Implemented in src/steam_totp.rs on hmac, sha1, and
base64. Test vectors are cross-checked against an independent HMAC-SHA1
implementation.
cargo testUnit tests cover the algorithm (known vectors, code stability across a 30s step,
malformed secrets); tests/cli.rs drives the built binary for each input source
and failure mode.