View Source ExOtp (ExOtp v0.0.1)

ExOtp allows you to create One-Time-Passwords, which can be either Time-based One-Time Passwords(TOTP) and Counter based OTPs(via HMAC-based One Time Passwords(HOTP)).

The library is primarily based on the PyOTP, and almost exactly mirrors their API as well. It follows the MFA standards defined in RFC4226(HOTP: an Hmac-Based One-Time Password Algorithm) and RFC6238(TOTP: Time-Based One-Time Password Algorithm).

The library provides the following features:

  • Generate TOTP or Counter based HOTP
  • Generate QR codes for OTPs
  • Generate random secret values(if required)

usage

Usage

totp

TOTP

  • Create a TOTP object using either a random secret or a user-provided secret as follows:

Example:

secret = ExOtp.random_secret()
#=> "uapgaiacdaptafbu"
totp = ExOtp.create_totp(secret, 30) # Specify interval for which the OTP will be valid.
#=> %ExOtp.Totp{
#  base: %ExOtp.Base{
#    digest: :sha,
#    digits: 6,
#    secret: "OVQXAZ3BNFQWGZDBOB2GCZTCOU======"
#  },
#  interval: 30
#}
  • Generate an otp using the totp object, for a given datetime value:

Example:

otp = ExOtp.generate_totp(totp, DateTime.utc_now())
#=> "967372"
  • Finally, you can check if the otp is valid using the otp and totp objects:

Example:

ExOtp.valid_totp?(totp, otp, DateTime.utc_now())
#=> true

hotp

HOTP

  • Create a HOTP object using either a random secret or a user-provided secret as follows:

Example:

secret = ExOtp.random_secret()
#=> "uapgaiacdaptafbu"
hotp = ExOtp.create_hotp(secret, 30) # Specify initial count
#=> %ExOtp.Hotp{
#  base: %ExOtp.Base{
#    digest: :sha,
#    digits: 6,
#    secret: "OVQXAZ3BNFQWGZDBOB2GCZTCOU======"
#  },
#  initial_count: 0
#}
  • Generate an otp using the hotp object, for a given datetime value:

Example:

otp = ExOtp.generate_hotp(hotp, DateTime.utc_now())
#=> "268374"
  • Finally, you can check if the otp is valid using the otp and hotp objects:

Example:

ExOtp.valid_hotp?(hotp, otp, 0) # Specify counter value
#=> true

qr-code-optional

QR Code(Optional)

  • Generate the provision URI for use with a QR code scanner built into MFA apps such as Google Authenticator.
  • Generate the QR code using the EQRCode libraby, which is an optional dependency.
  • Given a totp object and an otp, you can generate the QR code using:

Example:

totp
|> ExOtp.provision_uri_totp(otp, "test:shubham@google.com",issuer_name: "test")
|> ExOtp.generate_qr_code("code.svg")
#=> 09:51:17.102 [info]  QR code written to file: code.svg

Link to this section Summary

Link to this section Functions

Link to this function

create_hotp(secret, initial_count \\ 0)

View Source
@spec create_hotp(String.t(), integer()) :: ExOtp.Hotp.t()
Link to this function

create_totp(secret, interval \\ 30)

View Source
@spec create_totp(String.t(), integer()) :: ExOtp.Totp.t()
Link to this function

generate_hotp(hotp, count)

View Source
@spec generate_hotp(ExOtp.Hotp.t(), integer()) :: String.t()
Link to this function

generate_qr_code(input, filename \\ "code.svg")

View Source
Link to this function

generate_totp(totp, for_time, counter \\ 0)

View Source
@spec generate_totp(ExOtp.Totp.t(), DateTime.t(), integer()) :: String.t()
Link to this function

provision_uri_hotp(hotp, label, opts \\ [])

View Source
@spec provision_uri_hotp(ExOtp.Hotp.t(), String.t(), keyword()) :: String.t()
Link to this function

provision_uri_totp(totp, label, opts \\ [])

View Source
@spec provision_uri_totp(ExOtp.Totp.t(), String.t(), keyword()) :: String.t()
Link to this function

random_secret(length \\ 16)

View Source
@spec random_secret(integer()) :: no_return() | String.t()
Link to this function

valid_hotp?(hotp, otp, counter)

View Source
@spec valid_hotp?(ExOtp.Hotp.t(), String.t(), integer()) :: boolean()
Link to this function

valid_totp?(totp, otp, for_time \\ DateTime.utc_now(), valid_window \\ 0)

View Source
@spec valid_totp?(ExOtp.Totp.t(), String.t(), DateTime.t(), integer()) :: boolean()