gws.lib.otp

Generate and check HOTP and TOTP one-time passwords.

This package implements HMAC-based (HOTP, RFC 4226) and time-based (TOTP, RFC 6238) one-time passwords, as used by multi-factor authentication. It also creates otpauth:// key URIs for authenticator apps and random secrets.

All functions accept an optional Options object. Options that are not set are taken from DEFAULTS (30 second step, 6 digits, SHA-1, tolerance of one step).

Example:

import time
import gws.lib.otp

secret = gws.lib.otp.random_secret()
uri = gws.lib.otp.totp_key_uri(secret, 'GWS', 'user@example.com')
ok = gws.lib.otp.check_totp(user_input, secret, int(time.time()))

References

https://datatracker.ietf.org/doc/html/rfc4226 https://datatracker.ietf.org/doc/html/rfc6238 https://github.com/google/google-authenticator/wiki/Key-Uri-Format

Source code: gws.lib.otp

Package Contents

gws.lib.otp.base32_decode(s: str) → bytes

Decode a base32 string.

Parameters:

s – Base32 string.

Returns:

Decoded bytes.

gws.lib.otp.base32_encode(s: str | bytes) → str

Encode a string or bytes as base32.

Parameters:

s – Value to encode. Strings are encoded as UTF-8 first.

Returns:

Base32 string.

gws.lib.otp.check_totp(input: str, secret: str, timestamp: int, options: Options | None = None) → bool

Check if a TOTP token is valid.

Compares the input against the TOTP tokens within the tolerance window (timestamp-step*tolerance...timestamp+step*tolerance).

Parameters:
  • input – Token entered by the user.

  • secret – Shared secret.

  • timestamp – Unix timestamp.

  • options – Generation options.

Returns:

True if the input matches one of the tokens in the window.

gws.lib.otp.DEFAULTS
gws.lib.otp.hotp_key_uri(secret: str | bytes, issuer_name: str, account_name: str, counter: int, options: Options | None = None) → str

Create an HOTP key URI for authenticator apps.

Parameters:
  • secret – Shared secret, encoded as base32 in the URI.

  • issuer_name – Issuer name, e.g. the application name.

  • account_name – Account name, e.g. the user login.

  • counter – Initial counter value.

  • options – Generation options. Only non-default values are included in the URI.

Returns:

An otpauth://hotp/... URI.

gws.lib.otp.new_hotp(secret: str | bytes, counter: int, options: Options | None = None) → str

Generate an HOTP token as per RFC 4226 section 5.3.

Parameters:
  • secret – Shared secret.

  • counter – Counter value.

  • options – Generation options.

Returns:

The token as a string of digits.

gws.lib.otp.new_totp(secret: str | bytes, timestamp: int, options: Options | None = None) → str

Generate a TOTP token as per RFC 6238 section 4.2.

Parameters:
  • secret – Shared secret.

  • timestamp – Unix timestamp.

  • options – Generation options.

Returns:

The token as a string of digits.

class gws.lib.otp.Options(*args, **kwargs)

Bases: gws.Data

OTP generation options.

algo: str

Hash algorithm name, as in hashlib, e.g. sha1.

length: int

Number of digits in a token.

start: int

Start time (Unix timestamp) for TOTP counting.

step: int

TOTP time step in seconds.

tolerance: int

Number of time steps before and after the current one that are also accepted.

gws.lib.otp.random_secret(base32_length: int = 32) → str

Generate a random secret of printable ASCII characters.

The secret length is chosen so that its base32 encoding is exactly base32_length characters long.

Parameters:

base32_length – Length of the base32-encoded secret, must be a multiple of 8.

Returns:

The secret.

Raises:

ValueError – If base32_length is not a multiple of 8.

gws.lib.otp.totp_key_uri(secret: str | bytes, issuer_name: str, account_name: str, options: Options | None = None) → str

Create a TOTP key URI for authenticator apps.

Parameters:
  • secret – Shared secret, encoded as base32 in the URI.

  • issuer_name – Issuer name, e.g. the application name.

  • account_name – Account name, e.g. the user login.

  • options – Generation options. Only non-default values are included in the URI.

Returns:

An otpauth://totp/... URI.