Open jjude opened 9 years ago
Looking at the implementation, I think I can answer this. The Wikipedia article on TOTP notes, emphasis mine,
Both the server and the client compute the token, then the server checks if the token supplied by the client matches the locally generated token. Some servers allow codes that should have been generated before or after the current time in order to account for slight clock skews, network latencies and user delays.
pyotp, simply, does not (see here). It would be great if this could be an option, I think.
the only totp python package that have time skew support is SpookyOTP, this should be easy to make it support, if anyone do the task.
I am repurposing this issue for skew support, and changing the title accordingly. If anyone has a preferred API for how this would work, please comment here.
From https://tools.ietf.org/html/rfc6238#section-6:
Because of possible clock drifts between a client and a validation
server, we RECOMMEND that the validator be set with a specific limit
to the number of time steps a prover can be "out of synch" before
being rejected.
This limit can be set both forward and backward from the calculated
time step on receipt of the OTP value. If the time step is
30 seconds as recommended, and the validator is set to only accept
two time steps backward, then the maximum elapsed time drift would be
around 89 seconds, i.e., 29 seconds in the calculated time step and
60 seconds for two backward time steps.
This would mean the validator could perform a validation against the
current time and then two further validations for each backward step
(for a total of 3 validations). Upon successful validation, the
validation server can record the detected clock drift for the token
in terms of the number of time steps. When a new OTP is received
after this step, the validator can validate the OTP with the current
timestamp adjusted with the recorded number of time-step clock drifts
for the token.
Also, it is important to note that the longer a prover has not sent
an OTP to a validation system, the longer (potentially) the
accumulated clock drift between the prover and the verifier. In such
cases, the automatic resynchronization described above may not work
if the drift exceeds the allowed threshold. Additional
authentication measures should be used to safely authenticate the
prover and explicitly resynchronize the clock drift between the
prover and the validator.
It seems unambiguous that a "max_skew" parameter is needed, in number of time steps. The questions I have are:
Was this resolved in a commit?
There is a new parameter, verify(valid_window=...)
, which allows for a fixed amount of skew, just like max_skew
above. There is no resync capability yet.
Why would there need to be resync capabilities? Your computer isn't going to jump a second ahead or a second behind. The reason why it initially failed was because such a reason and TOTP implementation requests that there is a TTL component. Is this really necessary for the library to have (especially since you have to take latency into account and have the user give you the ms delay and fix and yada yada)
Please read the RFC, it explains the use case for clock skew support and resynchronization.
Still have similar issue in 2023, always my first probe fails even my keys are the same and interval is setup on 30.
Clock skew is supported via the valid_window
keyword argument.
Because resync is stateful, I don't think this library will fully support resync functionality directly. I think what we need in PyOTP to support resync is the ability to return where in the valid window the code was accepted, and documentation on how to use that.
Consider this test:
Sample output is:
I have seen this in production. I don't know why it fails sometimes. Any idea why? And how I can go about fixing it? Thank you, Joseph