otpgo

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2020 License: MIT Imports: 13 Imported by: 4

README

otpgo

HMAC-Based and Time-Based One-Time Password (HOTP and TOTP) library for Go. Implements RFC 4226 and RFC 6238.

License Go Report Card Test Status Coverage Status PkgGoDev Latest Release

Contents

Supported Operations

  • Generate HOTP and TOTP codes.
  • Verify HOTP an TOTP codes.
  • Export OTP config as a Google Authenticator URI.
  • Export OTP config as a QR code image (used to register secrets in authenticator apps).
  • Export OTP config as a JSON.

Reading Material

Usage

Generating Codes

The simplest way to generate codes is to create the HOTP/TOTP struct and call Generate()

// 
// HMAC-Based
//

// Will use all default values, counter starts in 0
h := otpgo.HOTP{}
token, _ := h.Generate()

// Increment counter and generate next code
h.Counter++
token2, _ := h.Generate()

//
// Time-Based
//

// Will use all default values
t := otpgo.TOTP{}
token, _ := t.Generate()

Each type allows customization. For HMAC-Based tokens you can specify:

  • Key: Secret string, base32 encoded
  • Counter: Unsigned int
  • Leeway: Unsigned int
  • Algorithm: One of HmacSHA1, HmacSHA256 or HmacSHA512
  • Length: Length1 up to Length8

For Time-Based tokens you can specify:

  • Key: Secret string, base32 encoded
  • Period: Integer, period length in seconds
  • Delay: Integer, acceptable number of steps for validation
  • Algorithm: One of HmacSHA1, HmacSHA256 or HmacSHA512
  • Length: Length1 up to Length8
Verifying Codes

Once you receive a token from the user you can verify it by specifying the expected parameters and calling Validate(token string).

// 
// HMAC-Based
//
h := otpgo.HOTP{
    Key: "my-secret-key",
    Counter: 123, // The expected counter
}
ok, _ := h.Validate("the-token")

//
// Time-Based
//
t := otpgo.TOTP{
    Key: "my-secret-key",
}
ok, _ = t.Validate("the-token")

When calling HOTP.Validate() note that the internal counter will be increased if validation is successful, so that the next valid token will correspond to the increased counter.

Both HOTP and TOTP will accept tokens that match the exact Counter/Timestamp or a token within the specified Leeway/Delay.

Registering With Authenticator Apps

Most authenticator apps will give the user 2 options to register a new account: scan a QR code which contains all config and secrets for the OTP generation, or manually enter the secret key and additional info (such as username and issuer). The former being the preferred way because of the ease of use and the avoidance of human error.

QR Code

To generate the QR code just get the KeyUri and call the QRCode method:

otp := otpgo.TOTP{}
base64EncodedQRImage, _ := otp.
   KeyUri("john.doe@example.org", "A Company").
   QRCode()

// Then use base64EncodedQRImage however you like
// e.g.: send it to the client to display as an image
Manual registration

Manual registration usually requires the user to type in the OTP config parameters by hand. The KeyUri type can be easily JSON encoded to then send the params to an external caller or any other place.

otp := otpgo.TOTP{
    Key: "YOUR_KEY",
    Period: 30,
    Delay: 1,
    Algorithm: config.HmacSHA1,
    Length: 6
}
ku := otp.KeyUri("john.doe@example.org", "A Company")
jsonKeyUri, _ := json.Marshal(ku)

// Then use jsonKeyUri however you like
// e.g.: send it to the client for further processing

Defaults

If caller doesn't provide a custom configuration when generating OTPs. The library will ensure the following default values (any empty value will be filled).

HOTP Parameters
Parameter Default Value
Leeway 1 counter down & up
Hash / Algorithm SHA1
Length 6
Key 64 random bytes base32 encoded
TOTP Parameters
Parameter Default Value
Period 30 seconds
Delay 1 period under & over
Hash / Algorithm SHA1
Length 6
Key 64 random bytes base32 encoded

Documentation

Index

Constants

View Source
const (
	// TOTPDefaultPeriod is the default time period to use if none is provided by the caller.
	TOTPDefaultPeriod = 30
	// TOTPDefaultDelay is the default acceptable delay window. A value of 1
	// means the OTP will be valid if it coincides with the calculated token for
	// the current time step, the next one or the one before.
	TOTPDefaultDelay = 1
)
View Source
const (
	// HOTPDefaultLeeway is the default acceptable look-ahead look-behind window.
	// A value of 1 means the OTP will be valid if it coincides with the
	// calculated token for the current counter, the next one or the one before.
	HOTPDefaultLeeway uint64 = 1
)
View Source
const RandomKeyLength = 64

RandomKeyLength is the recommended length for the key used to generate OTPs. This length will be used to generate default keys (in HOTP.ensureKey and TOTP.ensureKey), when the caller does not provide one explicitly.

Variables

This section is empty.

Functions

This section is empty.

Types

type ErrorInvalidKey

type ErrorInvalidKey struct {
	// contains filtered or unexported fields
}

The ErrorInvalidKey represents an invalid key used to generate OTPs.

func (ErrorInvalidKey) Error

func (eik ErrorInvalidKey) Error() string

type HOTP

type HOTP struct {
	Key       string               `json:"key"`       // Secret base32 encoded string
	Counter   uint64               `json:"counter"`   // Current value to calculate around
	Leeway    uint64               `json:"leeway"`    // Acceptable steps for sync error
	Algorithm config.HmacAlgorithm `json:"algorithm"` // Hash algorithm to use in the calculation
	Length    config.Length        `json:"length"`    // Length of the resulting code
}

The HOTP type used to generate HMAC-Based One-Time Passwords.

func (*HOTP) AsUrlValues added in v0.2.0

func (h *HOTP) AsUrlValues(issuer string) url.Values

AsUrlValues returns the HOTP parameters represented as url.Values.

func (*HOTP) Generate

func (h *HOTP) Generate() (string, error)

Generate a HMAC-Based One-Time Password.

func (*HOTP) KeyUri added in v0.2.0

func (h *HOTP) KeyUri(accountName, issuer string) *authenticator.KeyUri

KeyUri return an authenticator.KeyUri configured with the current HOTP params.

  • accountName is the username or email of the account
  • issuer is the site or org

func (*HOTP) Validate

func (h *HOTP) Validate(token string) (bool, error)

Validate will try to check if the provided token is a valid OTP for the current HOTP config. If the validation is successful the internal Counter will be incremented by one.

type TOTP

type TOTP struct {
	Key       string               `json:"key"`       // Secret base32 encoded string
	Period    int                  `json:"period"`    // Number of seconds the TOTP is valid
	Delay     int                  `json:"delay"`     // Acceptable steps for network delay
	Algorithm config.HmacAlgorithm `json:"algorithm"` // Hash algorithm to use in the calculation
	Length    config.Length        `json:"length"`    // Length of the resulting code
}

The TOTP type used to generate Time-Based One-Time Passwords.

func (*TOTP) AsUrlValues added in v0.2.0

func (t *TOTP) AsUrlValues(issuer string) url.Values

AsUrlValues returns the TOTP parameters represented as url.Values.

func (*TOTP) Generate

func (t *TOTP) Generate() (string, error)

Generate a Time-Based One-Time Password.

func (*TOTP) KeyUri added in v0.2.0

func (t *TOTP) KeyUri(accountName, issuer string) *authenticator.KeyUri

KeyUri return an authenticator.KeyUri configured with the current TOTP params.

  • accountName is the username or email of the account
  • issuer is the site or org

func (*TOTP) Validate

func (t *TOTP) Validate(token string) (bool, error)

Validate will try to check if the provided token is a valid OTP for the current TOTP config.

If the TOTP struct is using all the default values the config will be compatible with the Google Authenticator app, as well as most other apps.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL