I tested your code and the code has no problem and the generated otp is valid for up to 5 minutes.
You can create a timer for further investigation.
I think this part of document can help you :
In an ideal world both the client and the server's system time are
correct to the second with NIST or other authoritative time standards.
This would ensure that the generated code is always correct. If at all
possible, sync the system time as closely as with NIST.
There are cases where this simply isn't possible. Perhaps you are
writing an app to generate codes for use with a server who's time is
significantly off. You can't control the erroneous time of the server.
You could set your system clock to match but then your time would be
off significantly which isn't the desired result. There is a class
called TimeCorrection that helps with these cases.
A time correction object creates an offset that can be used to correct
(at least for the purposes of this calculation) the time relative to
the incorrect system time.
It is created as follows
var correction = new TimeCorrection(correctTime);
Where the correct
time parameter is a DateTime object that represents the current
correct (at least for the purposes of verification) UTC time. For this
to work there needs to be some way to get an instance of the current
acceptable time. This could be done with an NTP (NTP with NIST is
coming soon in this library) or looking for a Date response header
from an HTTP request or some other way.
Once this instance is created it can be used for a long time as it
always will use the current system time as a base to apply the
correction factor. The object is threadsafe and thus can be used by
multiple threads or web requests simultaneously.
There is an overload that takes both the correct time and the
reference time to use as well. This can be used in cases where UTC
time isn't used.
The Totp class constructor can take a TimeCorrection object that will
be applied to all time calculations and verifications.
var totp = new Totp(secretKey, timeCorrection: correction);
ComputeTotp
at the end of that frame yourresult
might expire within a second. To overcome this you may set thewindow
parameter (var window = new VerificationWindow(previous:1, future:1);
). – Arnhem