Category: Access and AuthenticationUpdated 2026-10-18

TOTP

TOTP (Time-based One-Time Password) is an algorithm defined in RFC 6238 that turns a shared secret and the current time into a short numeric code that, by default, changes every 30 seconds. It extends the counter-based HOTP of RFC 4226 and is what authenticator apps generate when you use a one-time code as a second factor.

How TOTP works

TOTP is built on HOTP. RFC 4226 defines HOTP(K,C) as a truncated HMAC-SHA-1 of a shared secret K and an 8-byte counter C. It requires codes of at least six digits and a shared secret of at least 128 bits, and recommends 160 bits. RFC 6238 replaces the counter with time: TOTP = HOTP(K, T), where T = (current Unix time - T0) / X, rounded down. The defaults are a time step X of 30 seconds and T0 of 0, the Unix epoch, and HMAC-SHA-256 or HMAC-SHA-512 may replace SHA-1.

Both sides hold the same secret, usually copied once from a QR code, and each computes the code on its own. Nothing is sent to your phone at login. The server compares what you type with its own result and tolerates small clock drift: RFC 6238 recommends allowing at most one time step for network delay. It also says a verifier must not accept a second attempt of an OTP that has already been validated.

Setting up TOTP for SSH through PAM

On Debian and Ubuntu the libpam-google-authenticator package provides pam_google_authenticator.so. Each user creates a secret once. According to the module documentation, it is saved in ~/.google_authenticator:

google-authenticator -t -d -r 3 -R 30 -e 10

These flags choose time-based codes, disallow reuse of a code, allow at most 3 logins per 30 seconds and generate 10 emergency codes (the maximum). Then wire it into PAM and sshd:

# /etc/pam.d/sshd
auth required pam_google_authenticator.so

# /etc/ssh/sshd_config
UsePAM yes
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

The nullok option lets users without a secret log in with no code, which helps during rollout but must be removed afterwards. Validate with sudo sshd -t, check that timedatectl shows a synchronised clock, and test in a new session while an old one stays open. The full order of steps is in the SSH two-factor guide linked below.

Limits, drift and common mistakes

Where TOTP fits in hardening

TOTP adds something you have to the key you already use for SSH, so a copied private key alone no longer opens the server. It is a sensible second factor for administrator accounts and costs nothing, but it is the weaker option: CISA describes FIDO/WebAuthn as the widely available phishing-resistant method, so choose a hardware key where you can, as covered under FIDO2 and WebAuthn.

Roll it out in this order:

  1. Finish SSH hardening and key-based login first.
  2. Follow the SSH two-factor authentication guide for the PAM and sshd changes.
  3. Enrol administrators first and give automation its own restricted keys, since a job cannot type a code.
  4. Keep emergency codes offline and a provider console available, and know the steps in the SSH lockout recovery guide.

The PAM entry explains the module stack that carries the code check.

Related terms: Two-factor authentication, PAM, FIDO2 and WebAuthn, Key-based authentication, SSH.

Frequently asked questions

What does TOTP stand for and how does it work?

TOTP stands for Time-based One-Time Password. The server and your authenticator app share a secret and both compute a code from that secret and the current time, which by default changes every 30 seconds.

Why does my TOTP code not work?

The most common cause is clock drift between the device and the server. The Google Authenticator PAM module tolerates about 30 seconds by default and can adjust to a larger skew after three consecutive logins, so check that both clocks are synchronised.

What is the difference between TOTP and HOTP?

HOTP, from RFC 4226, derives a code from a counter that advances with each use. TOTP, from RFC 6238, replaces the counter with the current time divided into steps, so codes expire by themselves.

Is TOTP phishing-resistant?

No. NIST SP 800-63B says OTP authentication is not phishing-resistant, because a typed code is not bound to the session and can be relayed to the real service. A FIDO2 hardware key does not have this weakness.

What if I lose my phone with the authenticator app?

Use one of the emergency codes generated by google-authenticator, up to 10 single-use codes that you should keep offline. If you have none, you need another way in, such as a provider console or rescue mode, and then you can create a new secret.

Want to see where your own server stands?

Run the free, read-only server check, or open the Security Lab and watch the detect, contain, recover, verify loop in action.

Get your free server checkOpen the Security Lab