otp

package module
v0.0.0-...-ced4aea Latest Latest
Warning

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

Go to latest
Published: Apr 22, 2025 License: BSD-3-Clause Imports: 9 Imported by: 0

README

otp

GoDoc CI

This repository contains a Go package to generate single use authenticator codes using the HOTP (RFC 4226) or TOTP (RFC 6238) algorithm.

Documentation

Overview

Package otp generates single use authenticator codes using the HOTP or TOTP algorithms specified in RFC 4226 and RFC 6238 respectively.

See https://tools.ietf.org/html/rfc4226, https://tools.ietf.org/html/rfc6238

Example
package main

import (
	"crypto/sha256"
	"fmt"
	"log"

	"github.com/wryhuman/otp"
)

func fixedTime(z uint64) func() uint64 { return func() uint64 { return z } }

func main() {
	cfg := otp.Config{
		Hash:   sha256.New, // default is sha1.New
		Digits: 8,          // default is 6

		// By default, time-based OTP generation uses time.Now.  You can plug in
		// your own function to control how time steps are generated.
		// This example uses a fixed time step so the output will be consistent.
		TimeStep: fixedTime(1),
	}

	// 2FA setup tools often present the shared secret as a base32 string.
	// ParseKey decodes this format.
	if err := cfg.ParseKey("MFYH A3DF EB2G C4TU"); err != nil {
		log.Fatalf("Parsing key: %v", err)
	}

	fmt.Println("HOTP", 0, cfg.HOTP(0))
	fmt.Println("HOTP", 1, cfg.HOTP(1))
	fmt.Println()
	fmt.Println("TOTP", cfg.TOTP())
}
Output:

HOTP 0 59590364
HOTP 1 86761489

TOTP 86761489

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultHOTP

func DefaultHOTP(key string, counter uint64) (string, error)

DefaultHOTP generates an HTOP for the specified counter using the default settings (compatible with Google Authenticator) based on the given key. An error is reported if the key is invalid.

func DefaultTOTP

func DefaultTOTP(key string) (string, error)

DefaultTOTP generates a TOTP for the current time step using the default settings (compatible with Google Authenticator) based on the given key. An error is reported if the key is invalid.

func FormatAlphabet

func FormatAlphabet(alphabet string) func([]byte, int) string

FormatAlphabet constructs a formatting function that truncates the counter hash per RFC 4226 and assigns code digits using the letters of the given alphabet string. Code digits are expanded from most to least significant.

func ParseKey

func ParseKey(s string) ([]byte, error)

ParseKey parses a key encoded as base32, the format used by common two-factor authentication setup tools. Whitespace is ignored, case is normalized, and padding is added if required.

func TimeWindow

func TimeWindow(n int) func() uint64

TimeWindow returns a time step generator that yields the number of n-second intervals elapsed at the current wallclock time since the Unix epoch.

func Truncate

func Truncate(digest []byte) uint64

Truncate truncates the specified digest using the algorithm from RFC 4226. Only the low-order 31 bits of the value are populated; the rest are zero.

Note that RFC 6238 stipulates the same truncation algorithm regardless of the length of the chosen digest.

Types

type Config

type Config struct {
	// Key is the shared secret used to generate OTP codes.
	// This field must be set for codes to be generated.
	// The value must not be encoded in base32 or similar.
	Key string

	// Hash, if non-nil, is used to construct the hash for OTP generation.
	// If nil, the default is sha1.New.
	Hash func() hash.Hash

	// TimeStep, if non-nil, returns the current time window to use for TOTP
	// generation each time it is called. If nil, TimeWindow(30) is used.
	TimeStep func() uint64

	// Counter is the current HOTP counter value. It is incremented each time
	// the Next method is called.
	Counter uint64

	// Digits indicates the number of digits a generated code will have.
	// If zero or negative, the default is 6.
	Digits int

	// Format, if set, is called with the counter hash to format a code of the
	// specified length. By default, the code is truncated per RFC 4226 (see
	// Truncate) and formatted as decimal digits (0..9).
	//
	// If Format returns a string of the wrong length, code generation panics.
	Format func(hash []byte, length int) string
}

Config holds the settings that control generation of authentication codes. The only required field is Key. The other fields may be omitted, and will use default values compatible with the Google authenticator.

Example (CustomFormat)
package main

import (
	"fmt"
	"log"

	"github.com/wryhuman/otp"
)

func fixedTime(z uint64) func() uint64 { return func() uint64 { return z } }

func main() {
	// Use settings compatible with Steam Guard: 5 characters and a custom alphabet.
	cfg := otp.Config{
		Digits:   5,
		Format:   otp.FormatAlphabet("23456789BCDFGHJKMNPQRTVWXY"),
		TimeStep: fixedTime(9876543210),
	}
	if err := cfg.ParseKey("CQKQ QEQR AAR7 77X5"); err != nil {
		log.Fatalf("Parsing key: %v", err)
	}

	fmt.Println(cfg.TOTP())
}
Output:

FKNK3
Example (RawFormat)
package main

import (
	"encoding/base64"
	"fmt"
	"log"

	"github.com/wryhuman/otp"
)

func main() {
	// The default formatting functions use the RFC 4226 truncation rules, but a
	// custom formatter may do whatever it likes with the HMAC value.
	// This example converts to base64.
	cfg := otp.Config{
		Digits: 10,
		Format: func(hash []byte, nb int) string {
			return base64.StdEncoding.EncodeToString(hash)[:nb]
		},
	}
	if err := cfg.ParseKey("MNQWE YTBM5 SAYTS MVQXI"); err != nil {
		log.Fatalf("Parsing key: %v", err)
	}
	fmt.Println(cfg.HOTP(17))
}
Output:

j0fLbXLh1Z

func (Config) HOTP

func (c Config) HOTP(counter uint64) string

HOTP returns the HOTP code for the specified counter value.

func (*Config) Next

func (c *Config) Next() string

Next increments the counter and returns the HOTP corresponding to its new value.

func (*Config) ParseKey

func (c *Config) ParseKey(s string) error

ParseKey parses a base32 key using the top-level ParseKey function, and stores the result in c.

func (Config) TOTP

func (c Config) TOTP() string

TOTP returns the TOTP code for the current time step. If the current time step value is t, this is equivalent to c.HOTP(t).

Directories

Path Synopsis
Package otpauth handles the URL format used to specify OTP parameters.
Package otpauth handles the URL format used to specify OTP parameters.

Jump to

Keyboard shortcuts

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