Base32 secrets with a length not a multiple of 8 may produce incorrect codes
tommilligan opened this issue · comments
Due to an underlying bad base32 implementation (speakeasyjs/base32.js#4), base32 encoded secrets that are not of length 8, 16, 24, 32 etc. may produce invalid codes.
This behaviour depends on the value of the secret itself. For a comparison with Python's pyotp
libaray, see these examples: pyauth/pyotp#115
This may be the underlying cause of the following issues:
Example: an incorrect code is generated for the secret S46SQCPPTCNPROMHWYBDCTBZXV
(length 26).
> speakeasy.totp({"secret":"S46SQCPPTCNPROMHWYBDCTBZXV","encoding":"base32","time":1612380872})
'184825'
The python pyotp
library produces a different value for the same inputs.
In [16]: pyotp.totp.TOTP("S46SQCPPTCNPROMHWYBDCTBZXV").at(datetime.fromtimestamp(1612380872))
Out[16]: '100172'