otp

package module
v0.0.0-...-16c78e9 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2025 License: MIT Imports: 14 Imported by: 0

README

OTP(HOTP/TOTP) package for Golang

This is a simple OTP(HOTP/TOTP) implementation in Go that can be used with the Google Authenticator app. It only support HMAC-SHA1, HMAC-SHA256, and HMAC-SHA512.

Note: All the functions to generate and validate the OTP expect the secret to be unencoded(raw bytes). If you want to use base32encoded secret make sure to decode it first by calling otp.DecodeBase32Secret utility function. Also, there is a function to generate a random base32 encoded secret GenerateBase32Secret.

Simple OTP Example

Basic 6 digits HMAC-SHA1 HOTP
digit := otp.DigitSix
counter := uint64(0}
// generate HMAC-SHA1 TOTP code with 6 digit
otpCode, err := otp.GenerateHOTPCode(rawByteSecret, counter, digit)
fmt.Println(otp.ZeroFill(otpCode, digit))
Basic 6 digits HMAC-SHA1 TOTP with 30 seconds duration
digit := otp.DigitSix
// generate HMAC-SHA1 TOTP code with 6 digit and 30 seconds duration.
otpCode, err := otp.GenerateTOTPCode(rawByteSecret, time.Now(), digit)
fmt.Println(otp.ZeroFill(otpCode, digit))
Custom 8 Digits OTP with HMAC-SHA256/HMAC-SHA512
digit := otp.DigitEight
counter := uint64(0)
// HOTP HMAC-SHA256
otpCode, err := otp.GenerateHOTPCodeAlgo(otp.AlgoSHA256, rawByteSecret, counter, digit)
fmt.Println(otp.ZeroFill(otpCode, digit))

// TOTP HMAC-SHA512
otpCode, err = otp.GenerateTOTPCodeAlgo(otp.AlgoSHA512, rawByteSecret, time.Now(), digit)
fmt.Println(otp.ZeroFill(otpCode, digit))

TOTP for Google Authenticator

Generating Key
// This will generate key for 6 digits OTP that can be used by Google 
// Authenticator App. The period duration will always be 30 seconds.
key, err := otp.GenerateGoogleAuthKey(otp.GoogleAuthKeyParam{
			Issuer:           "Example",
			AccountName:      "alice@example.com",
			Type:             otp.TypeTOTP,
			SecretByteLength: 10,
})

// prints the key
fmt.Println(key.String()) // it returns a url encoded otp key
// Or, generates a QR code that can be scanned by the app.
GenerateQRCode(key.String()) 
Validating
secret := key.Secret // get the secret from the key
rawByteSecret, err := otp.DecodeBase32Secret(secret)
var otpInput string
fmt.Scanf("%s", &otpInput)
code, err := strconv.Atoi(otpInput)
ok, err := otp.ValidateTOTPCode(int32(code), rawByteSecret, time.Now(), otp.DigitSix)
if ok {
	// Valid OTP
}

TOTP with custom duration

Generating the code
counter := otp.GetTOTPCounter(time.Now(), 20)
otpCode, err := otp.GenerateHOTPCode(rawByteSecret, counter, digit)
fmt.Println(otp.ZeroFill(otpCode, digit))
Validating the code
var otpInput string
fmt.Scanf("%s", &otpInput)
code, err := strconv.Atoi(otpInput)
counter := otp.GetTOTPCounter(time.Now(), 20)
otpCode, err := otp.ValidateHOTPCode(rawByteSecret, counter, digit)
fmt.Println(otp.ZeroFill(otpCode, digit))

Documentation

Overview

Package otp provides functionalities for generating and validating HOTP(IETF RFC4226) and TOTP(IETF RFC6238) codes.

Index

Constants

View Source
const (
	AlgoSHA1   = "sha1"
	AlgoSHA256 = "sha256"
	AlgoSHA512 = "sha512"
)

Variables

This section is empty.

Functions

func DecodeBase32Secret

func DecodeBase32Secret(secret string) ([]byte, error)

DecodeBase32Secret decodes the encoded secret and returns its raw byte form to be used by the OTP functions

func DynamicTruncation

func DynamicTruncation(b []byte, d Digit) (int32, error)

DynamicTruncation as defined in the rfc4226#section-5.4

func GenerateBase32Secret

func GenerateBase32Secret(byteLen uint32, randomReader io.Reader) (string, error)

GenerateBase32Secret generates an otp secret with length = `byteLen` encoded in base32. This is required for the otp to work with Google Authenticator. If the randomReader is nil, it will use the default crypto/rand.Reader to read the bytes from.

func GenerateHOTPCode

func GenerateHOTPCode(secret []byte, counter uint64, d Digit) (int32, error)

GenerateHOTPCode calls GenerateHOTPCodeAlgo with algo = AlgoSHA1

func GenerateHOTPCodeAlgo

func GenerateHOTPCodeAlgo(a Algo, secret []byte, counter uint64, d Digit) (int32, error)

GenerateHOTPCodeAlgo generates an otp code based on `secret` using HMAC-<Algo> hashing algorithm and `counter` as its moving factor.

func GenerateRandomSecret

func GenerateRandomSecret(byteLen uint32, randomReader io.Reader) ([]byte, error)

GenerateRandomSecret generate random bytes with length `byteLen` from the randomReader. If the randomReader is nil, it will use the default crypto/rand.Reader to read the bytes from.

func GenerateTOTPCode

func GenerateTOTPCode(secret []byte, t time.Time, d Digit) (int32, error)

GenerateTOTPCode calls GenerateTOTPCodeAlgo with algo = AlgoSHA1

func GenerateTOTPCodeAlgo

func GenerateTOTPCodeAlgo(a Algo, secret []byte, t time.Time, d Digit) (int32, error)

GenerateTOTPCodeAlgo generates an otp code based on `secret` using HMAC-<Algo> hashing algorithm and `floor(t/30)` as its moving factor.

func GetTOTPCounter

func GetTOTPCounter(t time.Time, period int64) uint64

GetTOTPCounter converts time t into a counter that can be used as the moving factor for the HOTP.

func ValidateHOTPCode

func ValidateHOTPCode(code int32, secret []byte, counter uint64, d Digit) (bool, error)

ValidateHOTPCode calls ValidateHOTPCodeAlgo with algo = AlgoSHA1

func ValidateHOTPCodeAlgo

func ValidateHOTPCodeAlgo(a Algo, code int32, secret []byte, counter uint64, d Digit) (bool, error)

ValidateHOTPCodeAlgo validates an otp code based on `secret` using HMAC-<Algo> hashing algorithm and `counter` as its moving factor.

func ValidateTOTPCode

func ValidateTOTPCode(passcode int32, secret []byte, t time.Time, d Digit) (bool, error)

ValidateTOTPCode calls ValidateTOTPCodeAlgo with algo = AlgoSHA1

func ValidateTOTPCodeAlgo

func ValidateTOTPCodeAlgo(a Algo, passcode int32, secret []byte, t time.Time, d Digit) (bool, error)

ValidateTOTPCodeAlgo validates an otp code based on `secret` using HMAC-<Algo> hashing algorithm and `floor(t/30)` as its moving factor.

func ZeroFill

func ZeroFill(code int32, d Digit) string

Types

type Algo

type Algo string

func (Algo) Hash

func (a Algo) Hash() hash.Hash

type Digit

type Digit int

Digit define the type of the number of digit for the OTP. Currently the most common digits are 6 and 8.

const (
	DigitSix   Digit = 6
	DigitSeven Digit = 7
	DigitEight Digit = 8
)

func (Digit) Modulus

func (d Digit) Modulus() uint32

type GoogleAuthKey

type GoogleAuthKey struct {
	GoogleAuthKeyParam
	Secret string
}

GoogleAuthKey provides key that works with Google Authenticator or any clients that have a similar implementation.

func GenerateGoogleAuthKey

func GenerateGoogleAuthKey(p GoogleAuthKeyParam) (GoogleAuthKey, error)

GenerateGoogleAuthKey generates a new usable key for Google Authenticator.

func (*GoogleAuthKey) String

func (k *GoogleAuthKey) String() string

String encodes the key into a string url that can be shown as a QR code and then scanned by Google Authenticator.

type GoogleAuthKeyParam

type GoogleAuthKeyParam struct {
	// Issuer of the otp
	Issuer string
	// AccountName of the user
	AccountName string
	// Type of the OTP(hotp/totp)
	Type Type

	// SecretByteLength defines the length of bytes will be read from RandReader
	SecretByteLength uint32
	// RandReader is the reader to read random bytes from. If nil, then it will
	// use the crypto/rand.Reader.
	RandReader io.Reader
}

GoogleAuthKeyParam defines the structure of otp key supported by Google Authenticator App.

type Type

type Type string

Type define the type of the OTP(HOTP or TOTP)

const (
	TypeHOTP Type = "hotp"
	TypeTOTP Type = "totp"
)

Jump to

Keyboard shortcuts

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