Wrong one-time-password generated by cryptography.hazmat.primitives.twofactor.totp

Viewed 218

SOLVED:

Using code snippet from he PyOTP library to pad and encode the key before passing it to the algorithm.

        missing_padding = len(key) % 8
        if missing_padding != 0:
            key += '=' * (8 - missing_padding)
        byte_key = b32decode(key, casefold=True)
        totp = cryptography.hazmat.primitives.twofactor.totp.TOTP(
            byte_key,
            6,
            SHA1(),
            30,
            backend=default_backend(),
            enforce_key_length=False
        )
        print("{:<10} {}".format(account, totp.generate(time()).decode()))

I'm generating one-time passwords for 2-factor authentication using the cryptography and PyOTP libraries. However, the TOTP objects from the two libraries give different outputs despite using the same key. I suspect it's something to do whether the key should be provided as a string or bytes-like object, but I'm unsure about how to handle the encoding/decoding.

Snippet (key is provided as a string read from a (encrypted) file) ->

        totp = cryptography.hazmat.primitives.twofactor.totp.TOTP(
            key.encode(),
            6,
            SHA1(),
            30,
            backend=default_backend()
        )
        totp2 = pyotp.TOTP(key)
        print("{:<10} {}".format(
            account,
            totp.generate(time()).decode()),
            totp2.now()
        )

Result ->

Dropbox    508629 405771

The OTP generated by PyOTP is consistent with Google Authenticator.

0 Answers
Related