totp

package
v0.58.0 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2024 License: BSD-3-Clause Imports: 10 Imported by: 1

Documentation

Overview

Package totp implement Time-Based One-Time Password Algorithm based on RFC 6238 [1].

[1] https://tools.ietf.org/html/rfc6238

Index

Examples

Constants

View Source
const (
	CryptoHashSHA1   CryptoHash = CryptoHash(crypto.SHA1) // Default hash algorithm.
	CryptoHashSHA256            = CryptoHash(crypto.SHA256)
	CryptoHashSHA512            = CryptoHash(crypto.SHA512)
)

List of available hash function that can be used in TOTP.

See RFC 6238 Section 1.2.

View Source
const (
	DefHash = CryptoHashSHA1

	// DefCodeDigits default digits generated when verifying or generating
	// OTP.
	DefCodeDigits = 6
	DefTimeStep   = 30

	// DefStepsBack maximum value for stepsBack parameter on Verify.
	// The value 20 means the Verify() method will check maximum 20 TOTP
	// tokens or 10 minutes to the past.
	DefStepsBack = 20
)

Default value for hash, digits, time-step, and maximum step backs.

Variables

This section is empty.

Functions

This section is empty.

Types

type CryptoHash

type CryptoHash crypto.Hash

CryptoHash define an alias to limit the type of hash algorithm to be used in TOTP.

type Protocol

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

Protocol contain methods to work with TOTP using the number of digits and time steps defined from New().

func New

func New(cryptoHash CryptoHash, codeDigits, timeStep int) Protocol

New create TOTP protocol for prover or verifier using "cryptoHash" as the hmac-sha hash function, "codeDigits" as the number of digits to be generated and/or verified, and "timeStep" as the time divisor.

There are only three hash functions that can be used: SHA1, SHA256, and SHA512. Passing hash value other than that, will revert the value default to SHA1.

The maximum value for codeDigits parameter is 8.

func (*Protocol) Generate

func (p *Protocol) Generate(secret []byte) (otp string, err error)

Generate one time password using the secret and current timestamp.

func (*Protocol) GenerateN

func (p *Protocol) GenerateN(secret []byte, n int) (listOTP []string, err error)

GenerateN generate n number of passwords from (ts - 0*timeStep) until (ts - N*timeStep).

func (*Protocol) GenerateNWithTime

func (p *Protocol) GenerateNWithTime(ts time.Time, secret []byte, n int) (listOTP []string, err error)

GenerateNWithTime generate n number of passwords from (ts - 0*timeStep) until (ts - N*timeStep).

Example
package main

import (
	"encoding/hex"
	"fmt"
	"log"
	"time"

	"git.sr.ht/~shulhan/pakakeh.go/lib/totp"
)

func main() {
	var (
		secretHex = `3132333435363738393031323334353637383930`

		secret []byte
		err    error
	)

	secret, err = hex.DecodeString(secretHex)
	if err != nil {
		log.Fatal(err)
	}

	var (
		proto = totp.New(totp.CryptoHashSHA1, totp.DefCodeDigits, totp.DefTimeStep)
		ts    = time.Date(2024, time.January, 29, 23, 37, 0, 0, time.UTC)

		listOTP []string
	)

	listOTP, err = proto.GenerateNWithTime(ts, secret, 3)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(listOTP)
}
Output:

[933840 870583 802638]

func (*Protocol) GenerateWithTime

func (p *Protocol) GenerateWithTime(ts time.Time, secret []byte) (otp string, err error)

GenerateWithTime generate one time password using ts as time and secret.

Example
package main

import (
	"encoding/hex"
	"fmt"
	"log"
	"time"

	"git.sr.ht/~shulhan/pakakeh.go/lib/totp"
)

func main() {
	var (
		secretHex = `3132333435363738393031323334353637383930`

		secret []byte
		err    error
	)

	secret, err = hex.DecodeString(secretHex)
	if err != nil {
		log.Fatal(err)
	}

	var (
		proto = totp.New(totp.CryptoHashSHA1, totp.DefCodeDigits, totp.DefTimeStep)
		ts    = time.Date(2024, time.January, 29, 23, 37, 0, 0, time.UTC)

		otp string
	)

	otp, err = proto.GenerateWithTime(ts, secret)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(otp)
}
Output:

933840

func (*Protocol) Verify

func (p *Protocol) Verify(secret []byte, token string, stepsBack int) bool

Verify the token based on the prover secret key. It will return true if the token matched, otherwise it will return false.

The stepsBack parameter define number of steps in the pass to be checked for valid OTP. For example, if stepsBack = 2 and timeStep = 30, the time range to checking OTP is in between

(current_timestamp - (2*30)) ... current_timestamp

For security reason, the maximum stepsBack is limited to DefStepsBack.

Example
package main

import (
	"encoding/hex"
	"fmt"
	"log"

	"git.sr.ht/~shulhan/pakakeh.go/lib/totp"
)

func main() {
	var (
		secretHex = `3132333435363738393031323334353637383930`

		err    error
		secret []byte
	)

	secret, err = hex.DecodeString(secretHex)
	if err != nil {
		log.Fatal(err)
	}

	var (
		proto = totp.New(totp.CryptoHashSHA1, totp.DefCodeDigits, totp.DefTimeStep)

		otp string
	)

	otp, _ = proto.Generate(secret)

	if proto.Verify(secret, otp, 1) {
		fmt.Println(`Generated token is valid.`)
	} else {
		fmt.Printf(`Generated token is not valid.`)
	}

}
Output:

Generated token is valid.

Jump to

Keyboard shortcuts

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