Skip to content

Instantly share code, notes, and snippets.

@michaelkitson
Last active September 5, 2024 16:22
Show Gist options
  • Save michaelkitson/e3860a63ec3cbc574cbdd40d94d5695c to your computer and use it in GitHub Desktop.
Save michaelkitson/e3860a63ec3cbc574cbdd40d94d5695c to your computer and use it in GitHub Desktop.
A bash function to generate TOTP codes
#!/usr/bin/env bash
set -euo pipefail
# Dependencies: openssl, xxd, base32 (coreutils)
# generate_totp key [time_sec [digits]]
generate_totp() {
key=$1
key_hex=$(base32 -d <<<"$key" | xxd -plain)
time_sec=${2:-$(date +%s)}
digits=${3:-6}
time_step=$((time_sec / 30))
time_step_hex=$(printf "%016x" $time_step)
hash_hex=$(xxd -revert -plain <<< "$time_step_hex" | openssl sha1 -mac HMAC -macopt "hexkey:$key_hex" -binary | xxd -plain)
offset=$((16#${hash_hex:39}))
offset_str="${hash_hex:$((offset * 2)):8}"
byte0=$(((16#${offset_str:0:2} & 127) << 24))
byte1=$((16#${offset_str:2:2} << 16))
byte2=$((16#${offset_str:4:2} << 8))
byte3=$((16#${offset_str:6:2}))
bin_code=$((byte0 + byte1 + byte2 + byte3))
printf "%0${digits}d" $((bin_code % (10 ** digits)))
}
generate_totp AC6ZWNRLFOG5JUQHC5YW6BXX2K675AZL | tee >(pbcopy)
printf "\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment