# `passlib.totp` – TOTP / Two Factor Authentication

Added in version 1.7.

## 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.

See also

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

## TOTP Class

class passlib.totp.TOTP(key=None, format="base32", \*, new=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) –

      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) – 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) –

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

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

    - label (str) – 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 `to_uri()` for details.

    - issuer (str) – 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 `to_uri()` for details.

    - size (int) –

      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) –

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

      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) – Name of hash algorithm to use. Defaults to `"sha1"`. `"sha256"` and `"sha512"` are also accepted, per RFC 6238.

    - period (int) – The time-step period to use, in integer seconds. Defaults to `30`.

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 `TOTP.new()`, to deserialization methods such as `TOTP.from_source()`.

classmethod TOTP.new()

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

classmethod TOTP.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 `from_uri()`

  - Any other strings are handed off to `from_json()`

  - Dicts are handed off to `from_dict()`

  Parameters:

    source – Serialized TOTP object.

  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 `TOTP.using()` for how to configure application secrets.

  Returns:

    a `TOTP` instance.

classmethod TOTP.from_uri(uri)

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

  Returns:

    `TOTP` instance.

  Raises:

    ValueError – if the uri cannot be parsed or contains errors.

  See also

  Configuring Clients tutorial for a usage example

classmethod TOTP.from_json(source)

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

  Parameters:

    json – Serialized output from `to_json()`, as str or ascii bytes.

  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 `TOTP.using()` for how to configure application secrets.

  Returns:

    a `TOTP` instance.

  See also

  Storing TOTP instances tutorial for a usage example

classmethod TOTP.from_dict(source)

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

  Parameters:

    source – dict containing serialized TOTP key & configuration.

  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 `TOTP.using()` for how to configure application secrets.

  Returns:

    A `TOTP` instance.

  See also

  Storing TOTP instances tutorial for a usage example

## Factory Creation

One powerful method offered by the TOTP class is `TOTP.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:

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

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

  Parameters:

    digits, alg, period, issuer:

    All these options are the same as in the `TOTP` constructor, and the resulting class will use any values you specify here as the default for all TOTP instances it creates.

  Parameters:

    - wallet – Optional `AppWallet` that will be used for encrypting/decrypting keys.

    - encrypt_cost (secrets, secrets_path,) – If specified, these options will be passed to the `AppWallet` constructor, allowing you to directly specify the secret keys that should be used to encrypt & decrypt stored keys.

  Returns:

    subclass of `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}

  See also

  Creating TOTP Instances and Storing TOTP instances tutorials for a usage example

## 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 `TOTP.to_uri()` and `TOTP.to_json()`:

TOTP.key

  secret key as raw bytes

TOTP.hex_key

  secret key encoded as hexadecimal string

TOTP.base32_key

  secret key encoded as base32 string

TOTP.label = None

  default label for `to_uri()`

TOTP.issuer = None

  default issuer for `to_uri()`

TOTP.digits = 6

  number of digits in the generated tokens.

TOTP.alg = 'sha1'

  name of hash algorithm in use (e.g. `"sha1"`)

TOTP.period = 30

  number of seconds per counter step. (TOTP uses an internal time-derived counter which increments by 1 every `period` seconds).

TOTP.changed = False

  Flag set by deserialization methods to indicate the object needs to be re-serialized. This can be for a number of reasons – encoded using deprecated format, or encrypted using a deprecated key or too few rounds.

## Token Generation

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

TOTP.generate(time=None)

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

  Parameters:

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

  Returns:

    A `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'

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:

class passlib.totp.TotpToken

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

  token = None

    Token as decimal-encoded ascii string.

  expire_time

    Timestamp marking end of period when token is valid

  counter = None

    HOTP counter value used to generate token (derived from time)

  remaining

    number of (float) seconds before token expires

  valid

    whether token is still 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()`:

TOTP.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 `float`, `int`, or `datetime`. if `None` (the default), uses current system time. this should correspond to the time the token was received from the client.

    - window (int) – 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 `period`.

    - skew (int) –

      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.

  Raises:

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

  Returns TotpMatch:

    Returns a `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

classmethod TOTP.verify(token, source, **kwds)

  Convenience wrapper around `TOTP.from_source()` and `TOTP.match()`.

  This parses a TOTP key & configuration from the specified source, and tries and match the token. It’s designed to parallel the `passlib.ifc.PasswordHash.verify()` method.

  Parameters:

    - token – Token string to match.

    - source – Serialized TOTP key. Can be anything accepted by `TOTP.from_source()`.

    - \*\*kwds – All additional keywords passed to `TOTP.match()`.

  Returns:

    A `TotpMatch` instance, or raises a `TokenError`.

See also

Verifying Tokens 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:

class passlib.totp.TotpMatch

  Object returned by `TOTP.match()` and `TOTP.verify()` on a successful match.

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

  counter = 0

    TOTP counter value which matched token. (Best practice is to subsequently ignore tokens matching this counter or earlier)

  time = 0

    Timestamp when verification was performed.

  expected_counter = 0

    Counter value expected for timestamp.

  skipped = 0

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

  expire_time = 0

    Timestamp marking end of period when token is valid

  cache_seconds = 60

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

  cache_time = 0

    Timestamp marking when counter has passed outside of verification window.

  This object will always have a `True` boolean value.

## 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 [3]. 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).

TOTP.to_uri(label=None, issuer=None)

  Serialize key and configuration into a URI, per Google Auth’s KeyUriFormat.

  Parameters:

    - label (str) –

      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) –

      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 `:`.

  Raises:

    ValueError –

    - if a label was not provided either as an argument, or in the constructor.

    - if the label or issuer contains invalid characters.

  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'

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

TOTP.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'

See also

- The `TOTP.from_source()` and `TOTP.from_uri()` constructors for decoding URIs.

- The Configuring Clients tutorial for details about these methods, and how to render URIs to a QR Code.

## Serialization Methods

The `TOTP.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. When application secrets are configured via `TOTP.using()`, these methods will automatically encrypt the resulting keys.

TOTP.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 `to_dict()`.

  Returns:

    json string containing serializes configuration & state.

TOTP.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 also

- The `TOTP.from_source()` and `TOTP.from_json()` constructors for decoding the results of these methods.

- The Storing TOTP instances tutorial for more details.

## Helper Methods

While `TOTP.generate()`, `TOTP.match()`, and `TOTP.verify()` automatically handle normalizing tokens & time values, the following methods are exposed in case they are useful in other contexts:

TOTP.normalize_token(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 `digits`, or use the class default.

  Parameters:

    token – token as ascii bytes, str, or an integer.

  Raises:

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

  Returns:

    token as `str`, containing only digits 0-9.

classmethod TOTP.normalize_time(time)

  Normalize time value to unix epoch seconds.

  Parameters:

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

  Returns:

    unix epoch timestamp as `int`.

## AppWallet

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

class passlib.totp.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 `TOTP.using()`.

  See also

  Storing TOTP instances for more details on this workflow.

  ### Arguments

  param 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)

    See also

    `generate_secret()` to create a secret with sufficient entropy

  param 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.

  param 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.

  param 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).

  `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

  has_secrets

    whether at least one application secret is present

  default_tag = None

    tag for default secret

  ### Semi-Private Methods

  The following methods are used internally by the `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.

  get_secret(tag)

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

  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 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(enckey)

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

    Parameters:

      source – source object, as returned by `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 package.

## Support Functions

passlib.totp.generate_secret(entropy=256)

  generate a random string suitable for use as an `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.

Footnotes

[1] (1,2)

TOTP Specification - RFC 6238

[2]

HOTP Specification - RFC 4226

[3]

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