One-Time Passwords

And How To Implement Them Using HMAC

By Sahand Saba / sahandsaba.com

Motivation

Problem of Authentication

  • Alice sends Bob message $m$.
  • Alice is the originator.
  • Bob is the receiver.
  • Authentication is confirming the identity of the orignator.
  • I.e. Bob wants to know originator is truly Alice.

Authentication Factors

Knowledge

Something the user knows. Can be static or dynamic.

  • Password (Static)
  • Birthdate (Static)
  • First car's model (Static)
  • Friends' faces (Dynamic)
  • Last payment made (Dynamic)

Authentication Factors

Ownership

Something the user owns.

  • Badge
  • ID card
  • USB key
  • Cellphone
  • Etc.

Authentication Factors

Inherence

Something inherent to the user.

  • DNA
  • Fingerprint
  • Face
  • Etc.

Password-Based Authentication

Advantages

  • Simple to implement
  • No specialized hardware required

Password-Based Authentication

Weaknesses - Part I

Passwords are static knowledge factors.

  • Guessed
  • Stolen
  • Found by brute-force
  • Found by social engineering (e.g. phishing)

Password-Based Authentication

Weaknesses - Part II

Passwords are often implemented incorrecty. Case in point:

Source: Sophos Security, based on Adobe's 153-million user database leak

Password-Based Authentication

Weaknesses - Part III

And related XKCD:

Source: xkcd.com

Two-Factor Authentication

Use two factors instead of one for authentication.

Two common implementations are:

  • Secret questions
  • One-time passwords

Secret Questions

Weaknesses

Secret questions are also static knowledge factors.

  • Guessing
  • Brute-force search
  • Social engineering (e.g. "Find out your superhero name!")

Motivation

Conclusions

  • Passwords alone are insecure.
  • Secret questions are insecure second factors.

One-Time Passwords

Advantages and Disadvantages

  • Introduce an ownership factor.
  • Considered to be more secure than secret questions.
  • Downside: Conventionally require specialized hardware.

One-Time Passwords

Example Hardware I

HSBC One-Time Password Hardware

One-Time Passwords

Example Hardware II

YubiKeys - Offered by YubiCo

One-Time Passwords

Solutions Without Specialized Hardware

  • Specialized hardware can be costly and inconvenient
  • Solution: Cellphones
  • Users almost always have them
  • Provide alternative communication channel: phone calls and SMS

One-Time Passwords

Example Hardware III

Google Authenticator Running on Cellphones

One-Time Passwords

Basic Protocal

  • Bob generates a random one-time password (OTP).
  • Bob sends Alice the OTP.
  • Alice uses the OTP for authentication.
  • Security relies on a "verified" channel of communication, e.g. SMS, phone call, or physically giving the hardware to the user.
  • Used by Facebook.

One-Time Passwords

Alternative Protocal

  • Alice and Bob share a secret key
  • Pseudorandom function (PRF) used to generate OTP
  • Input to PRF is shared key and a synchronization value.

One-Time Passwords

Synchronization Modes

Two common ways to synchronize the OTP's:

  • Counter-based
  • Time-based

Hash-based One-Time Passwords (HOTP)

Counter-Based - RFC 4226

  • HMAC-SHA-1 as the pseudorandom function
  • Counter-based OTP generation
  • OTP is generated as $$Truncate(Hash(k \| C))$$
  • Counter value $C$ incremented after each generation
  • $Truncate$ extracts $D$ decimal digits from HMAC's output
  • RFC standard provides a mechanism for re-synchronization

Time-based One-Time Passwords (TOTP)

Time-Based - RFC 6238

  • Based off of HOTP
  • OTP is generated as $$Truncate(Hash(k \| T))$$
  • With $$ T = \left \lfloor \frac{T_{current} - T_0}{X} \right \rfloor$$
  • $X$ determines how long OTP is valid for
  • Recommended value for $X$ is 30 seconds

Time-based One-Time Passwords (TOTP)

Time-Based - RFC 6238

Python implementation of OTP generation, taken from pyotp:


def generate_otp(self, input):
        """
        @param [Integer] input the number used seed the HMAC
        Usually either the counter, or the computed integer
        based on the Unix timestamp
        """
        hmac_hash = hmac.new(
            self.byte_secret(),
            self.int_to_bytestring(input),
            self.digest,
        ).digest()
        
        offset = ord(hmac_hash[19]) & 0xf
        code = ((ord(hmac_hash[offset]) & 0x7f) << 24 |
            (ord(hmac_hash[offset + 1]) & 0xff) << 16 |
            (ord(hmac_hash[offset + 2]) & 0xff) << 8 |
            (ord(hmac_hash[offset + 3]) & 0xff))
        return code % 10 ** self.digits
    

Demo!

Python and Flask on Heroku + Google Authenticator

Finally, here is a example of implementing TOTP-based authentication using Python running on Heroku.

Here it is!

Thank you

By Sahand Saba / sahandsaba.com