otp

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2022 License: MIT Imports: 17 Imported by: 0

README

otp

One Time Password package for Go/Golang developers

中文文档

Contents

What is OTP

A one-time password (OTP) is an automatically generated numeric string that authenticates a user for a single transaction or login session.

The most important advantage addressed by OTPs is that, in contrast to static passwords, they are not vulnerable to replay attacks.

There are two kinds of OTP which are HOTP and TOTP. The vast majority of OTP today is TOTP. Very few people still use HTOP.

By the way, the TOTP RFC document has a mistake. More details can be found here if you are interested.

How to Use

Before using this package, you need to install Go and set your Go workspace first.

  1. Use the below Go command to install the package.
$ go get -u github.com/lucasbbb/otp
  1. Import it in your code.
import "github.com/lucasbbb/otp"
  1. Generate a Key and show it's QR code.
func main() {
    http.HandleFunc("/image", QRImage)
    _ = http.ListenAndServe(":6789", nil)
}

func QRImage(w http.ResponseWriter, req *http.Request) {
    secret, _ := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString("INEECT2TEBEVGICBEBGECRCEIVJA")
    key := otp.Key{
        Issuer:  "example",
        Account: "foo",
        Typ:     "totp",
        Secret:  secret,
    }
    image, _ := key.QRImage(256)
    _, _ = w.Write(image)
}
  1. User scan the QR code with Google Authenticator or other apps.

Google Authenticator

  1. Compare the code with the sever generated code.
func VerifyOTP(accountName, code string) {
	now := time.Now()
	// Get user's secret from DATABASE or other repository.
	// SELECT secret FORM user WHERE `account_name` = accountName
	secret, _ := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString("INEECT2TEBEVGICBEBGECRCEIVJA")
	res := otp.NewTOTP(secret).Validate(now, code)
	if res {
		// Continue your business logic.
	} else {
		// Abort.
	}
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidType     = fmt.Errorf("valid type must be hotp or totp")
	ErrSecretRequired  = fmt.Errorf("the secret is required")
	ErrInvalidSecret   = fmt.Errorf("the secret must be a base32 encoded string")
	ErrInvalidDigits   = fmt.Errorf("parse digits to int failed")
	ErrCounterRequired = fmt.Errorf("the counter is required for hotp")
	ErrInvalidCounter  = fmt.Errorf("parse counter to uint failed")
	ErrInvalidPeriod   = fmt.Errorf("parse period to uint failed")
)

Functions

This section is empty.

Types

type HOTP

type HOTP struct {
	Key []byte
}

func NewHOTP

func NewHOTP(key []byte) HOTP

func (HOTP) Generate

func (otp HOTP) Generate(in interface{}, opts ...Option) string

Generate https://datatracker.ietf.org/doc/html/rfc4226#section-5.3

func (HOTP) Validate

func (otp HOTP) Validate(in interface{}, code string, opts ...Option) bool

Validate return true if the code matched the generated code

type Key

type Key struct {
	Typ       string
	Issuer    string
	Account   string
	Secret    []byte
	Period    int
	Counter   uint64
	Digits    int
	Algorithm string
	// contains filtered or unexported fields
}

func (*Key) Alg

func (k *Key) Alg() func() hash.Hash

func (*Key) QRImage

func (k *Key) QRImage(size int) ([]byte, error)

func (*Key) RawURL

func (k *Key) RawURL() string

type OTP

type OTP interface {
	Generate(in interface{}, opts ...Option) string
	Validate(in interface{}, code string, opts ...Option) bool
}

type Option

type Option func(*Options)

func WithDigit

func WithDigit(digit int) Option

WithDigit The default digit = 6

func WithHashFunc

func WithHashFunc(f func() hash.Hash) Option

WithHashFunc The default hash func is sha1.New You can use other hash func such as: sha256.New, sha512.New, md5.New

func WithStartTime

func WithStartTime(start int64) Option

WithStartTime The default start time = 0 The UNIX time to start counting time steps

func WithTimeStep

func WithTimeStep(step int) Option

WithTimeStep The default time step is 30s.

type Options

type Options struct {
	Digit     int
	HashFunc  func() hash.Hash
	TimeStep  int
	Leeway    int
	StartTime int64
}

func NewOptions

func NewOptions() *Options

type TOTP

type TOTP struct {
	Key []byte
}

func NewTOTP

func NewTOTP(key []byte) *TOTP

func (TOTP) Generate

func (otp TOTP) Generate(in interface{}, opts ...Option) string

func (TOTP) Validate

func (otp TOTP) Validate(in interface{}, code string, opts ...Option) bool

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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