Skip to content

Instantly share code, notes, and snippets.

@resilar
Created September 21, 2021 13:29
Show Gist options
  • Save resilar/11a87124c1cfbea075b111af8da270ae to your computer and use it in GitHub Desktop.
Save resilar/11a87124c1cfbea075b111af8da270ae to your computer and use it in GitHub Desktop.
POSIX shell implementation of TOTP using OpenSSL
#!/bin/sh
TOTP() {
TOTP_SECRET="${1:-GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ}"
TOTP_DIGITS="${2:-6}"
TOTP_STEP="${3:-30}"
TOTP_TIME="${4:-"$(date '+%s')"}"
TOTP_COUNTER="$((TOTP_TIME / TOTP_STEP))"
printf '%016x' "${5:-$TOTP_COUNTER}" | xxd -r -p \
| openssl dgst -sha1 -hmac "$(printf '%s' "$TOTP_SECRET" | base32 -d)" \
| sed 's/^.*\([0-9a-f]\{39\}\)\([0-9a-f]\)$/\1\2 0x\2/' \
| if read -r HMAC POS; then
OFFSET="$((2 * POS))"
MODULO="$(printf "1%0${TOTP_DIGITS}d" 0)"
VALUE="0x$(printf '%s' "$HMAC" | cut -b "$((OFFSET+1))-$((OFFSET+8))")"
printf "%0${TOTP_DIGITS}d\n" "$(((VALUE & 0x7FFFFFFF) % MODULO))"
fi
}
TOTP "$(printf '12345678901234567890' | base32)" 8 30 123456789 # 54781240
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment