speakeasyjs / speakeasy

**NOT MAINTAINED** Two-factor authentication for Node.js. One-time passcode generator (HOTP/TOTP) with support for Google Authenticator.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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'