TOTP - Time-based One Time Password
TOTP is a time based One Time Password standard. The TOTP authenticator works with TOTP based keyfob devices. Both hardware based and software based. The TOTP is suitable as a second factor during authentication, and usually less suitable as a standalone single factor, as it relies on the device only, which may not be protected by any passwords or pin codes.
Configuring an Authenticator#
To configure the TOTP authenticator it needs the following:
- A data store for the pre-shared keys or a data-source supporting buckets, for generated keys
- An account manager to find the users and devices
- The TOTP specific settings such as window size, clock skew, interval and algorithm
Configuration Settings#
- Account manager: Used to search for the devices associated with the account of the authenticated (with the first factor) user.
- Bucket data-source: Used to save the used OTPs in order to disallow a code from being used more times successively.
- Algorithm: The algorithm that is used to generate the OTP. It is used on authentication and registration. Algorithms supported are
SHA1,SHA256,SHA512. - Allow registration during login: Boolean flag that shows or hides the
Registerbutton from the templates - Allow multiple device registration: Boolean flag to enable registering multiple devices for one account.
- Clock Skew: Time in seconds the TOTP device time is allowed to drift in respect to the server time.
- Delay window: A number that indicates how many intervals a OTP can be used after expired.
- Digits: The number of digits the OTP consists of.
- Interval: The time in seconds the OTP is valid for (affected by delay window).
- Device Expiration: If set, indicates when the device expires. This is saved on the device store during registration.
- Auto Redirect Enabled: When enabled, user is redirected directly to the registration page if no TOTP device is already registered.
- Throttler service: A specific Throttler service used to throttle verification of one-time passwords, applied per account. When not referenced, the default Throttler service is used, if one is configured. See Throttling OTP verification.
- Client IP throttler: An optional Throttler service applied to the pair of client IP address and account, in addition to the per-account throttler. See Throttling OTP verification.
- Key Distribution Settings:
- Pre-shared key config:
- Attribute data-source: The repository where the id of the device can be used to find the key to validate the OTP.
- Generated key config:
- Bucket data-source: The data source id where the generated key will be stored.
- Issuer: Used by some OTP authenticator apps to help the user identify which OTP to use.
- Allow user to set device alias: Boolean indicates if the set-alias screen will be shown during registration.
- Pre-shared key config:
It is not recommended to use this authenticator for single-factor authentication. Even though, when used as a single factor it will show a page asking the user for its username, in order to allow registration, a required-authenticator for registration is required. In case one is not configured, the server will respond with HTTP code 500 Internal Error when a user is trying to access the registration endpoint.
Multiple Device registration#
When the option to allow the registration of multiple devices is enabled, a new device registration will add the new device to the existing device or devices that the user can use to authenticate. This is contrary to when this setting is disabled, in which case the user can only use the most recently registered device to authenticate.
The TOTP authenticator does not provide a feature to manage devices. This could be custom built using the GraphQL API.
Configuring for pre-shared keys#
The pre-shared keys is a mapping of device id (typically serial number) to the symmetric key. The key should be encoded using base32.
When a request is received for an OTP, the user is looked up using the account manager. Thereafter the device id or serial number is found on the user and used to lookup the actual key using the data source configured for id -> key mappings.
The authenticator also uses the Bucket data sources (since 2.4.0). This is used to store used OTPs so that they can only be used once to authenticate a user.
Make sure the Bucket tables are defined in the data source.
Example configuration for pre-shared keys#
<authenticator>
<id>totp1</id>
<totp xmlns="https://curity.se/ns/ext-conf/totp">
<account-manager>
<id>DefaultAccountManager</id>
</account-manager>
<bucket>
<data-source>DefaultHSQLDB</data-source>
</bucket>
<device-type>idsvr-totp</device-type>
<clock-skew>0</clock-skew>
<interval>30</interval>
<digits>6</digits>
<algorithm>sha1</algorithm>
<pre-shared-key-config>
<key-repository>
<data-source>KeyRepo</data-source>
</key-repository>
</pre-shared-key-config>
</totp>
</authenticator>
Only the key is mandatory to be in the response of the key repository. Any other parameter returned will override the configuration of the authenticator (for that specific device).
Example response of key repository JSON data-source#
{
"clock_skew": 0,
"interval": 60,
"delay_window": 1,
"algorithm": "SHA1",
"digits": 6,
"key": "KNCUGUSFKRFUKWJR"
}
Configuring for generated keys#
When configured to use generated keys, the authenticator also uses the Bucket data source to save the key for the device. Also, when registering a new device, a QR code is shown to the user (and optionally a page where he/she can enter an alias for the device). The QR code can be scanned with TOTP mobile apps, like Google Authenticator, FreeOTP and Yubico Authenticator.
Example configuration for generated keys#
<authenticator>
<id>totp1</id>
<totp xmlns="https://curity.se/ns/ext-conf/totp">
<account-manager>
<id>DefaultAccountManager</id>
</account-manager>
<bucket>
<data-source>DefaultHSQLDB</data-source>
</bucket>
<device-type>idsvr-totp</device-type>
<clock-skew>0</clock-skew>
<interval>30</interval>
<digits>6</digits>
<algorithm>sha256</algorithm>
<generated-shared-key-config>
<bucket>
<data-source>KeyRepo</data-source>
</bucket>
<issuer>Example.com</issuer>
<allow-user-to-set-device-alias>true</allow-user-to-set-device-alias>
</generated-shared-key-config>
</totp>
</authenticator>
Throttling OTP verification#
Verification of one-time passwords during authentication is throttled to limit online brute-force guessing. Two layers are available, each enforced by a Throttler service:
- Per account (always on when a Throttler service is available). Attempts are keyed on the user name stored on the account, so every spelling of the same user name shares one budget. The service is resolved in this order: the Throttler service referenced under
throttler-service, otherwise the server’s default Throttler service, otherwise no throttling. - Per client IP address and account (optional,
client-ip-throttler). Attempts are keyed on the pair of client IP address and user name. This layer is checked first, and an attempt it denies is not counted against the account budget. Configure it with a stricter budget than the per-account throttler: a single source is then cut off quickly, before it can exhaust the account’s budget. This is especially relevant when TOTP is used as a first factor, where anyone who knows a user name can otherwise lock the user out by submitting wrong codes.
A throttled attempt is rejected with the message with key error.too-many-attempts (HAAPI problem type https://curity.se/problems/too-many-attempts) without verifying the code, and a successful verification resets the throttling state of the account, so a user who mistypes a few codes is not penalized on later logins.
Each attempt counts once against the budget, regardless of how many devices it is checked against. When Allow multiple device registration is enabled, one attempt verifies the code against every active device of the account, so the number of codes effectively tried grows with the number of registered devices. The budget should be sized taking this into consideration.
The client IP address is the one the server considers the request to originate from, taking white-listed reverse proxies into account. If all traffic appears to come from a single address, for example an unlisted load balancer, the client IP layer degrades to a second per-account limit; the per-account layer remains the backstop in every case.
When only the per-account layer is configured, an attacker who knows a user name can exhaust that account’s budget with wrong codes and lock the legitimate user out until the throttling interval passes. Choose a budget that leaves room for genuine mistakes, and consider the client IP layer when TOTP is a first factor.
Example configuration with throttling#
<authenticator>
<id>totp1</id>
<totp xmlns="https://curity.se/ns/ext-conf/totp">
<account-manager>
<id>DefaultAccountManager</id>
</account-manager>
<bucket>
<data-source>DefaultHSQLDB</data-source>
</bucket>
<throttler-service>
<throttler>totp-account-throttler</throttler>
</throttler-service>
<client-ip-throttler>
<throttler>totp-client-ip-throttler</throttler>
</client-ip-throttler>
<generated-key-config>
<bucket>
<data-source>KeyRepo</data-source>
</bucket>
</generated-key-config>
</totp>
</authenticator>
Google Authenticator#
Google Authenticator mobile app is more restrictive than some implementations. It requires the authenticator to be configured with a 30 seconds interval, SHA1 as algorithm and no clock_skew. The authenticator’s default settings are compliant with Google Authenticator mobile app, just configure the mandatory fields to get started. Keep in mind that a generated-key-config should be configured in this case.
Yubico Authenticator#
Yubico Authenticator mobile app can work with any of the supported algorithms (SHA1, SHA256 or SHA512). The interval is also configurable, and likewise the number of digits. Digits can be 6, 7 or 8.
FreeOTP#
FreeOTP is similar to Yubico in configuration, but more restrictive on the number of digits (it only accepts 6 or 8). All supported algorithms by this authenticator are also supported by FreeOTP and the interval is also possible to configure.
Automatic Login#
When enabled, automatic login is available after successfully registering a new device.