Skip to content

passlib.totp -- TOTP / Two Factor Authentication

The passlib.totp module provides totp / two factor authentication.

Warning

Changed in 1.7: Added.

Overview

The passlib.totp module provides a number of classes for implementing two-factor authentication (2FA) using the TOTP 1 specification. This page provides a reference to all the classes and methods in this module.

Passlib's TOTP support is centered around the TOTP class. There are also some additional helpers, including the AppWallet class, which helps to securely encrypt TOTP keys for storage.

Tip

  • TOTP Tutorial -- Overview of this module and walkthrough of how to use it.

TOTP Class

TOTP

TOTP(
    key=None,
    format="base32",
    new=False,
    digits=None,
    alg=None,
    size=None,
    period=None,
    label=None,
    issuer=None,
    changed=False,
    **kwds,
)

Helper for generating and verifying TOTP codes.

Given a secret key and set of configuration options, this object offers methods for token generation, token validation, and serialization. It can also be used to track important persistent TOTP state, such as the last counter used.

This class accepts the following options (only key and format may be specified as positional arguments).

Parameters:

  • key (str, default: None ) –

    The secret key to use. By default, should be encoded as a base32 string (see format for other encodings).

    Exactly one of key or new=True must be specified.

  • format (str, default: 'base32' ) –

    The encoding used by the key parameter. May be one of: "base32" (base32-encoded string), "hex" (hexadecimal string), or "raw" (raw bytes). Defaults to "base32".

  • new (bool, default: False ) –

    If True, a new key will be generated using :class:random.SystemRandom.

    Exactly one new=True or key must be specified.

  • label (str, default: None ) –

    Label to associate with this token when generating a URI. Displayed to user by most OTP client applications (e.g. Google Authenticator), and typically has format such as "John Smith" or "jsmith@webservice.example.org". Defaults to None. See :meth:to_uri for details.

  • issuer (str, default: None ) –

    String identifying the token issuer (e.g. the domain name of your service). Used internally by some OTP client applications (e.g. Google Authenticator) to distinguish entries which otherwise have the same label. Optional but strongly recommended if you're rendering to a URI. Defaults to None. See :meth:to_uri for details.

  • size (int, default: None ) –

    Number of bytes when generating new keys. Defaults to size of hash algorithm (e.g. 20 for SHA1).

    .. warning::

    Overriding the default values for ``digits``, ``period``, or ``alg`` may
    cause problems with some OTP client programs (such as Google Authenticator),
    which may have these defaults hardcoded.
    
  • digits (int, default: None ) –

    The number of digits in the generated / accepted tokens. Defaults to 6. Must be in range [6 .. 10].

    .. rst-class:: inline-title .. caution:: Due to a limitation of the HOTP algorithm, the 10th digit can only take on values 0 .. 2, and thus offers very little extra security.

  • alg (str, default: None ) –

    Name of hash algorithm to use. Defaults to "sha1". "sha256" and "sha512" are also accepted, per :rfc:6238.

  • period (int, default: None ) –

    The time-step period to use, in integer seconds. Defaults to 30.

    .. See the passlib documentation for a full list of attributes & methods.

key property writable

key

secret key as raw bytes

encrypted_key property writable

encrypted_key

secret key, encrypted using application secret. this match the output of :meth:AppWallet.encrypt_key, and should be treated as an opaque json serializable object.

hex_key property

hex_key

secret key encoded as hexadecimal string

base32_key property

base32_key

secret key encoded as base32 string

using classmethod

using(
    digits=None,
    alg=None,
    period=None,
    issuer=None,
    wallet=None,
    now=None,
    **kwds,
)

Dynamically create subtype of :class:!TOTP class which has the specified defaults set.

Parameters:

  • wallet –

    Optional :class:AppWallet that will be used for encrypting/decrypting keys.

  • encrypt_cost –

    If specified, these options will be passed to the :class:AppWallet constructor, allowing you to directly specify the secret keys that should be used to encrypt & decrypt stored keys.

Returns:

  • –

    subclass of :class:!TOTP.

    This method is useful for creating a TOTP class configured to use your application's secrets for encrypting & decrypting keys, as well as create new keys using it's desired configuration defaults.

    As an example::

    >>> # your application can create a custom class when it initializes
    >>> from passlib.totp import TOTP, generate_secret
    >>> TotpFactory = TOTP.using(secrets={"1": generate_secret()})
    
    >>> # subsequent TOTP objects created from this factory
    >>> # will use the specified secrets to encrypt their keys...
    >>> totp = TotpFactory.new()
    >>> totp.to_dict()
    {'enckey': {'c': 14,
      'k': 'H77SYXWORDPGVOQTFRR2HFUB3C45XXI7',
      's': 'G5DOQPIHIBUM2OOHHADQ',
      't': '1',
      'v': 1},
     'type': 'totp',
     'v': 1}
    

    .. seealso:: :ref:totp-creation and :ref:totp-storing-instances tutorials for a usage example

new classmethod

new(**kwds)

convenience alias for creating new TOTP key, same as TOTP(new=True)

pretty_key

pretty_key(format='base32', sep='-')

pretty-print the secret key.

This is mainly useful for situations where the user cannot get the qrcode to work, and must enter the key manually into their TOTP client. It tries to format the key in a manner that is easier for humans to read.

Parameters:

  • format –

    format to output secret key. "hex" and "base32" are both accepted.

  • sep –

    separator to insert to break up key visually. can be any of "-" (the default), " ", or False (no separator).

Returns:

  • –

    key as native string.

    Usage example::

    >>> t = TOTP('s3jdvb7qd2r7jpxx')
    >>> t.pretty_key()
    'S3JD-VB7Q-D2R7-JPXX'
    

normalize_time classmethod

normalize_time(time)

Normalize time value to unix epoch seconds.

Parameters:

  • time –

    Can be None, :class:!datetime, or unix epoch timestamp as :class:!float or :class:!int. If None, uses current system time. Naive datetimes are treated as UTC.

Returns:

  • –

    unix epoch timestamp as :class:int.

normalize_token

normalize_token(self_or_cls, token)

Normalize OTP token representation: strips whitespace, converts integers to a zero-padded string, validates token content & number of digits.

This is a hybrid method -- it can be called at the class level, as TOTP.normalize_token(), or the instance level as TOTP().normalize_token(). It will normalize to the instance-specific number of :attr:~TOTP.digits, or use the class default.

Parameters:

  • token –

    token as ascii bytes, str, or an integer.

Returns:

  • –

    token as :class:!str, containing only digits 0-9.

Raises:

  • ValueError –

    if token has wrong number of digits, or contains non-numeric characters.

generate

generate(time=None)

Generate token for specified time (uses current time if none specified).

Parameters:

  • time –

    Can be None, a :class:!datetime, or class:!float / :class:!int unix epoch timestamp. If None (the default), uses current system time. Naive datetimes are treated as UTC.

Returns:

  • –

    A :class:TotpToken instance, which can be treated as a sequence of (token, expire_time) -- see that class for more details.

    Usage example::

    >>> # generate a new token, wrapped in a TotpToken instance...
    >>> otp = TOTP('s3jdvb7qd2r7jpxx')
    >>> otp.generate(1419622739)
    <TotpToken token='897212' expire_time=1419622740>
    
    >>> # when you just need the token...
    >>> otp.generate(1419622739).token
    '897212'
    

verify classmethod

verify(token, source, **kwds)

Convenience wrapper around :meth:TOTP.from_source and :meth:TOTP.match.

This parses a TOTP key & configuration from the specified source, and tries and match the token. It's designed to parallel the :meth:passlib.ifc.PasswordHash.verify method.

Parameters:

  • token –

    Token string to match.

  • source –

    Serialized TOTP key. Can be anything accepted by :meth:TOTP.from_source.

  • \\*\\*kwds –

    All additional keywords passed to :meth:TOTP.match.

Returns:

  • –

    A :class:TotpMatch instance, or raises a :exc:TokenError.

match

match(
    token,
    time=None,
    window=30,
    skew=0,
    last_counter=None,
)

Match TOTP token against specified timestamp. Searches within a window before & after the provided time, in order to account for transmission delay and small amounts of skew in the client's clock.

Parameters:

  • token –

    Token to validate. may be integer or string (whitespace and hyphens are ignored).

  • time –

    Unix epoch timestamp, can be any of :class:!float, :class:!int, or :class:!datetime. if None (the default), uses current system time. this should correspond to the time the token was received from the client.

  • window (int, default: 30 ) –

    How far backward and forward in time to search for a match. Measured in seconds. Defaults to 30. Typically only useful if set to multiples of :attr:period.

  • skew (int, default: 0 ) –

    Adjust timestamp by specified value, to account for excessive client clock skew. Measured in seconds. Defaults to 0.

    Negative skew (the common case) indicates transmission delay, and/or that the client clock is running behind the server.

    Positive skew indicates the client clock is running ahead of the server (and by enough that it cancels out any negative skew added by the transmission delay).

    You should ensure the server clock uses a reliable time source such as NTP, so that only the client clock's inaccuracy needs to be accounted for.

    This is an advanced parameter that should usually be left at 0; The window parameter is usually enough to account for any observed transmission delay.

  • last_counter –

    Optional value of last counter value that was successfully used. If specified, verify will never search earlier counters, no matter how large the window is.

    Useful when client has previously authenticated, and thus should never provide a token older than previously verified value.

Returns:

  • –

    Returns a :class:TotpMatch instance on successful match. Can be treated as tuple of (counter, time). Raises error if token is malformed / can't be verified.

    Usage example::

    >>> totp = TOTP('s3jdvb7qd2r7jpxx')
    
    >>> # valid token for this time period
    >>> totp.match('897212', 1419622729)
    <TotpMatch counter=47320757 time=1419622729 cache_seconds=60>
    
    >>> # token from counter step 30 sec ago (within allowed window)
    >>> totp.match('000492', 1419622729)
    <TotpMatch counter=47320756 time=1419622729 cache_seconds=60>
    
    >>> # invalid token -- token from 60 sec ago (outside of window)
    >>> totp.match('760389', 1419622729)
    Traceback:
        ...
    InvalidTokenError: Token did not match
    

Raises:

  • ~passlib.exc.TokenError –

    If the token is malformed, fails to match, or has already been used.

from_source classmethod

from_source(source)

Load / create a TOTP object from a serialized source. This acts as a wrapper for the various deserialization methods:

  • TOTP URIs are handed off to :meth:from_uri
  • Any other strings are handed off to :meth:from_json
  • Dicts are handed off to :meth:from_dict

Parameters:

  • source –

    Serialized TOTP object.

Returns:

  • –

    a :class:TOTP instance.

Raises:

  • ValueError –

    If the key has been encrypted, but the application secret isn't available; or if the string cannot be recognized, parsed, or decoded.

    See :meth:TOTP.using() for how to configure application secrets.

from_uri classmethod

from_uri(uri)

create an OTP instance from a URI (such as returned by :meth:to_uri).

Returns:

  • –

    :class:TOTP instance.

Raises:

  • ValueError –

    if the uri cannot be parsed or contains errors.

    .. seealso:: :ref:totp-configuring-clients tutorial for a usage example

to_uri

to_uri(label=None, issuer=None)

Serialize key and configuration into a URI, per Google Auth's KeyUriFormat <http://code.google.com/p/google-authenticator/wiki/KeyUriFormat>_.

Parameters:

  • label (str, default: None ) –

    Label to associate with this token when generating a URI. Displayed to user by most OTP client applications (e.g. Google Authenticator), and typically has format such as "John Smith" or "jsmith@webservice.example.org".

    Defaults to label constructor argument. Must be provided in one or the other location. May not contain :.

  • issuer (str, default: None ) –

    String identifying the token issuer (e.g. the domain or canonical name of your service). Optional but strongly recommended if you're rendering to a URI. Used internally by some OTP client applications (e.g. Google Authenticator) to distinguish entries which otherwise have the same label.

    Defaults to issuer constructor argument, or None. May not contain :.

Returns:

  • –

    all the configuration information for this OTP token generator, encoded into a URI.

    These URIs are frequently converted to a QRCode for transferring to a TOTP client application such as Google Auth. Usage example::

    >>> from passlib.totp import TOTP
    >>> tp = TOTP('s3jdvb7qd2r7jpxx')
    >>> uri = tp.to_uri("user@example.org", "myservice.another-example.org")
    >>> uri
    'otpauth://totp/user@example.org?secret=S3JDVB7QD2R7JPXX&issuer=myservice.another-example.org'
    

    .. versionchanged:: 1.7.2

    This method now prepends the issuer URI label.  This is recommended by the KeyURI
    specification, for compatibility with older clients.
    

Raises:

  • ValueError –
    • if a label was not provided either as an argument, or in the constructor.
    • if the label or issuer contains invalid characters.

from_json classmethod

from_json(source)

Load / create an OTP object from a serialized json string (as generated by :meth:to_json).

Parameters:

  • json –

    Serialized output from :meth:to_json, as str or ascii bytes.

Returns:

  • –

    a :class:TOTP instance.

    .. seealso:: :ref:totp-storing-instances tutorial for a usage example

Raises:

  • ValueError –

    If the key has been encrypted, but the application secret isn't available; or if the string cannot be recognized, parsed, or decoded.

    See :meth:TOTP.using() for how to configure application secrets.

to_json

to_json(encrypt=None)

Serialize configuration & internal state to a json string, mainly useful for persisting client-specific state in a database. All keywords passed to :meth:to_dict.

Returns:

  • –

    json string containing serializes configuration & state.

from_dict classmethod

from_dict(source)

Load / create a TOTP object from a dictionary (as generated by :meth:to_dict)

Parameters:

  • source –

    dict containing serialized TOTP key & configuration.

Returns:

  • –

    A :class:TOTP instance.

    .. seealso:: :ref:totp-storing-instances tutorial for a usage example

Raises:

  • ValueError –

    If the key has been encrypted, but the application secret isn't available; or if the dict cannot be recognized, parsed, or decoded.

    See :meth:TOTP.using() for how to configure application secrets.

to_dict

to_dict(encrypt=None)

Serialize configuration & internal state to a dict, mainly useful for persisting client-specific state in a database.

Parameters:

  • encrypt –

    Whether to output should be encrypted.

    • None (the default) -- uses encrypted key if application secrets are available, otherwise uses plaintext key.
    • True -- uses encrypted key, or raises TypeError if application secret wasn't provided to OTP constructor.
    • False -- uses raw key.

Returns:

  • –

    dictionary, containing basic (json serializable) datatypes.

See below for all the TOTP methods & attributes...

Alternate Constructors

There are a few alternate class constructors offered. These range from simple convenience wrappers such as new(), to deserialization methods such as from_source(). These are all covered by the TOTP reference above: new(), from_source(), from_uri(), from_json(), and from_dict().

Factory Creation

One powerful method offered by the TOTP class is using(). This method allows you to quickly create TOTP subclasses with preconfigured defaults, for configuration application secrets and setting default TOTP behavior for your application: covered by the TOTP reference above.

Basic Attributes

All the TOTP objects offer the following attributes, which correspond to the constructor options above. Most of this information will be serialized by to_uri() and to_json(): these are all covered by the TOTP reference above (key, hex_key, base32_key, label, issuer, digits, alg, period, and changed).

Token Generation

Token generation is generally useful client-side, and for generating values to test your server implementation. There is one main generation method: generate().

Warning

Tokens should be displayed as strings, as they may contain leading zeros which will get stripped if they are first converted to an int.

TotpToken

The TOTP.generate method returns instances of the following class, which offers up detailed information about the generated token:

TotpToken

TotpToken(totp, token, counter)

Object returned by :meth:TOTP.generate. It can be treated as a sequence of (token, expire_time), or accessed via the following attributes:

.. autoattribute:: token .. autoattribute:: expire_time .. autoattribute:: counter .. autoattribute:: remaining .. autoattribute:: valid

.. warning:: the constructor signature is an internal detail, and is subject to change.

remaining property

remaining

number of (float) seconds before token expires

valid property

valid

whether token is still valid

start_time

start_time()

Timestamp marking beginning of period when token is valid

expire_time

expire_time()

Timestamp marking end of period when token is valid

Token Matching / Verification

Matching user-provided tokens is the main operation when implementing server-side TOTP support. Passlib offers one main method: TOTP.match, as well as a convenience wrapper TOTP.verify: both covered by the TOTP reference above.

Tip

totp-verifying tutorial for a usage example.

TotpMatch

If successful, the TOTP.verify method returns instances of the following class, which offers up detailed information about the matched token:

TotpMatch

TotpMatch(totp, counter, time, window=30)

Object returned by :meth:TOTP.match and :meth:TOTP.verify on a successful match.

It can be treated as a sequence of (counter, time), or accessed via the following attributes:

.. autoattribute:: counter :annotation: = 0

.. autoattribute:: time :annotation: = 0

.. autoattribute:: expected_counter :annotation: = 0

.. autoattribute:: skipped :annotation: = 0

.. autoattribute:: expire_time :annotation: = 0

.. autoattribute:: cache_seconds :annotation: = 60

.. autoattribute:: cache_time :annotation: = 0

This object will always have a True boolean value.

.. warning:: the constructor signature is an internal detail, and is subject to change.

expected_counter

expected_counter()

Counter value expected for timestamp.

skipped

skipped()

How many steps were skipped between expected and actual matched counter value (may be positive, zero, or negative).

expire_time

expire_time()

Timestamp marking end of period when token is valid

cache_seconds

cache_seconds()

Number of seconds counter should be cached before it's guaranteed to have passed outside of verification window.

cache_time

cache_time()

Timestamp marking when counter has passed outside of verification window.

Client Configuration Methods

Once a server has generated a new TOTP key & configuration, it needs to be communicated to the user in order for them to store it in a suitable TOTP client.

This can be done by displaying the key & configuration for the user to hand-enter into their client, or by encoding TOTP object into a URI 2. These configuration URIs can subsequently be displayed as a QR code, for easy transfer to many smartphone-based TOTP clients (such as Authy or Google Authenticator).

The to_uri() and pretty_key() methods are covered by the TOTP reference above.

Tip

  • The from_source and from_uri constructors for decoding URIs.
  • The totp-configuring-clients tutorial for details about these methods, and how to render URIs to a QR Code.

Serialization Methods

The to_uri() method is useful, but limited, because it requires additional information (label & issuer), and lacks the ability to encrypt the key. The TOTP provides the following methods for serializing TOTP objects to internal storage: to_json() and to_dict(), both covered by the TOTP reference above. When application secrets are configured via using(), these methods will automatically encrypt the resulting keys.

Tip

  • The from_source and from_json constructors for decoding the results of these methods.
  • The totp-storing-instances tutorial for more details.

Helper Methods

While generate(), match(), and verify() automatically handle normalizing tokens & time values, the following methods are exposed in case they are useful in other contexts: normalize_token() and normalize_time(), both covered by the TOTP reference above.

AppWallet

The AppWallet class is used internally by the using() method to store the application secrets provided for handling encrypted keys. If needed, they can also be created and passed in directly.

AppWallet

AppWallet(
    secrets=None,
    default_tag=None,
    encrypt_cost=None,
    secrets_path=None,
)

This class stores application-wide secrets that can be used to encrypt & decrypt TOTP keys for storage. It's mostly an internal detail, applications usually just need to pass secrets or secrets_path to :meth:TOTP.using.

.. seealso::

:ref:`totp-storing-instances` for more details on this workflow.

Arguments

Parameters:

  • secrets –

    Dict of application secrets to use when encrypting/decrypting stored TOTP keys. This should include a secret to use when encrypting new keys, but may contain additional older secrets to decrypt existing stored keys.

    The dict should map tags -> secrets, so that each secret is identified by a unique tag. This tag will be stored along with the encrypted key in order to determine which secret should be used for decryption. Tag should be string that starts with regex range [a-z0-9], and the remaining characters must be in [a-z0-9_.-].

    It is recommended to use something like a incremental counter ("1", "2", ...), an ISO date ("2016-01-01", "2016-05-16", ...), or a timestamp ("19803495", "19813495", ...) when assigning tags.

    This mapping be provided in three formats:

    • A python dict mapping tag -> secret
    • A JSON-formatted string containing the dict
    • A multiline string with the format "tag: value\ntag: value\n..."

    (This last format is mainly useful when loading from a text file via secrets_path)

    .. seealso:: :func:generate_secret to create a secret with sufficient entropy

  • secrets_path –

    Alternately, callers can specify a separate file where the application-wide secrets are stored, using either of the string formats described in secrets.

  • default_tag –

    Specifies which tag in secrets should be used as the default for encrypting new keys. If omitted, the tags will be sorted, and the largest tag used as the default.

    if all tags are numeric, they will be sorted numerically; otherwise they will be sorted alphabetically. this permits tags to be assigned numerically, or e.g. using YYYY-MM-DD dates.

  • encrypt_cost –

    Optional time-cost factor for key encryption. This value corresponds to log2() of the number of PBKDF2 rounds used.

    Warning

    The application secret(s) should be stored in a secure location by your application, and each secret should contain a large amount of entropy (to prevent brute-force attacks if the encrypted keys are leaked).

    :func:generate_secret is provided as a convenience helper to generate a new application secret of suitable size.

    Best practice is to load these values from a file via secrets_path, and then have your application give up permission to read this file once it's running.

    Public Methods

    .. autoattribute:: has_secrets .. autoattribute:: default_tag

    Semi-Private Methods

    The following methods are used internally by the :class:TOTP class in order to encrypt & decrypt keys using the provided application secrets. They will generally not be publically useful, and may have their API changed periodically.

has_secrets property

has_secrets

whether at least one application secret is present

get_secret

get_secret(tag)

resolve a secret tag to the secret (as bytes). throws a KeyError if not found.

encrypt_key

encrypt_key(key)

Helper used to encrypt TOTP keys for storage.

Parameters:

  • key –

    TOTP key to encrypt, as raw bytes.

Returns:

  • –

    dict containing encrypted TOTP key & configuration parameters. this format should be treated as opaque, and potentially subject to change, though it is designed to be easily serialized/deserialized (e.g. via JSON).

    .. note::

    This function requires installation of the external
    `cryptography <https://cryptography.io>`_ package.
    

    To give some algorithm details: This function uses AES-256-CTR to encrypt the provided data. It takes the application secret and randomly generated salt, and uses PBKDF2-HMAC-SHA256 to combine them and generate the AES key & IV.

decrypt_key

decrypt_key(enckey)

Helper used to decrypt TOTP keys from storage format. Consults configured secrets to decrypt key.

Parameters:

  • source –

    source object, as returned by :meth:encrypt_key.

Returns:

  • –

    (key, needs_recrypt) --

    **key** will be the decrypted key, as bytes.
    
    **needs_recrypt** will be a boolean flag indicating
    whether encryption cost or default tag is too old,
    and henace that key needs re-encrypting before storing.
    

    .. note::

    This function requires installation of the external
    `cryptography <https://cryptography.io>`_ package.
    

Support Functions

generate_secret

generate_secret(
    entropy=256, charset=BASE64_CHARS[:-2]
)

generate a random string suitable for use as an :class:AppWallet application secret.

Parameters:

  • entropy –

    number of bits of entropy (controls size/complexity of password).

Deviations

  • The TOTP Spec 1 includes an param (T0) providing an optional offset from the base time. Passlib omits this parameter (fixing it at 0), but so do pretty much all other TOTP implementations.

References

  • HOTP Specification - RFC 4226

  1. TOTP Specification - RFC 6238 ↩↩

  2. Google's OTPAuth URI format - https://github.com/google/google-authenticator/wiki/Key-Uri-Format ↩