While writing my post on YubiKey Manager and PowerShell: TOTP Credentials, I stumbled across the vampire “byte” (sorry) of OATH time-based one time passcodes (TOTP): clock skew or time drift.
This got me thinking about the impact of clock skew on the validity of OATH-TOTP codes. I modeled it (script/Gist linked below) and confirmed my theory that time drift has an incremental and linear effect on the validity of the resulting one time passcode.
With a 6 digit passcode and 30-second window, each second of skew introduces a 3.33% chance that the generated passcode will be invalid at any given time. More generally:
Odds (%) of bad OTP = |[clock skew in seconds]| * (100/[window length in seconds])
Or, the absolute value of clock skew in seconds, multiplied by the quantity 100 divided by the TOTP window length in seconds.
If your clock is 3 seconds off (using a standard 6 digit code with 30 second window), the probability that your OTP will be invalid is 10%. At 15 seconds off, the probability increases to 50%. When your time drift is greater than the window length, the generated TOTP code will be invalid 100% the time.
I am not incredibly proud of it, but I assembled and used this test script to generate random OATH-TOTP secrets and test the resulting one-time passcode with varying levels of time drift. My script relies heavily on the excellent work by ecspresso and jonfriesen surrounding TOTP implementation in PowerShell.
Clock drift is more of an issue with legacy hardware tokens with internal clocks (think RSA). Over time, these tokens fall out of sync and eventually become useless. With newer authentication devices that support OATH-TOTP (like the YubiKey), this is much less of a concern since the one-time passcodes are generated using the clock on the device the YubiKey is plugged into. Just make sure your device’s system clock is properly synchronizing to an authoritative time source!
This ended up being a fun and informative exercise. I am hopeful someone besides me finds it interesting and useful.