diff options
| author | Shulhan <m.shulhan@gmail.com> | 2020-12-23 21:58:27 +0700 |
|---|---|---|
| committer | Shulhan <m.shulhan@gmail.com> | 2020-12-23 21:58:27 +0700 |
| commit | ae0e03ebec6061d5a85ebe54ac4c77cef18f1972 (patch) | |
| tree | 67b3a21c5fb36ccf2b42579b77ff1f5a49f5f806 | |
| parent | f9804fe2bce4ff427391c433c93f9f70381ec57d (diff) | |
| download | pakakeh.go-ae0e03ebec6061d5a85ebe54ac4c77cef18f1972.tar.xz | |
totp: add method to generate n number of passwords
The GenerateN method will return list of password from
(current time - N*timeStep) until the current time.
| -rw-r--r-- | cmd/totp/main.go | 19 | ||||
| -rw-r--r-- | lib/totp/totp.go | 20 |
2 files changed, 32 insertions, 7 deletions
diff --git a/cmd/totp/main.go b/cmd/totp/main.go index f175827c..75aebc0b 100644 --- a/cmd/totp/main.go +++ b/cmd/totp/main.go @@ -7,6 +7,7 @@ import ( "crypto/sha1" "crypto/sha256" "crypto/sha512" + "encoding/base32" "flag" "fmt" "hash" @@ -22,8 +23,8 @@ func main() { flag.Usage = usage paramDigits := flag.Int("digits", 6, "number of digits to generated") - paramHash := flag.String("hash", "sha1", "hash names, valid values is sha1, sha256, sha512") - paramTimestep := flag.Int("timestep", 30, "time step in seconds") + paramHash := flag.String("alg", "sha1", "hash name, valid values is sha1, sha256, sha512") + paramTimestep := flag.Int("period", 30, "time step in seconds") paramHelp := flag.Bool("help", false, "show command usage") flag.Parse() @@ -45,19 +46,25 @@ func main() { } totproto := totp.New(hashFn, *paramDigits, *paramTimestep) - secret := []byte(os.Args[1]) - p0, err := totproto.Generate(secret) + secret, err := base32.StdEncoding.DecodeString(os.Args[1]) if err != nil { log.Fatal(err) } - fmt.Printf("%s\n", p0) + listOTP, err := totproto.GenerateN(secret, 3) + if err != nil { + log.Fatal(err) + } + + for _, otp := range listOTP { + fmt.Printf("%s\n", otp) + } } func usage() { log.Printf(`%s is command line interface to generate time-based one-time password. Usage: - %s [OPTIONS] <SECRET_KEY> + %s [OPTIONS] <BASE32-SECRET> Available OPTIONS: `, os.Args[0], os.Args[0]) diff --git a/lib/totp/totp.go b/lib/totp/totp.go index 98b7142a..fa5fe070 100644 --- a/lib/totp/totp.go +++ b/lib/totp/totp.go @@ -64,6 +64,24 @@ func (p *Protocol) Generate(secret []byte) (otp string, err error) { } // +// GenerateN generate n number of passwords from (current time - N*timeStep) +// until the curent time. +// +func (p *Protocol) GenerateN(secret []byte, n int) (listOTP []string, err error) { + mac := hmac.New(p.fnHash, secret) + ts := time.Now().Unix() + for x := 0; x < n; x++ { + t := ts - int64(x*p.timeStep) + otp, err := p.generateWithTimestamp(mac, t) + if err != nil { + return nil, fmt.Errorf("GenerateN: %w", err) + } + listOTP = append(listOTP, otp) + } + return listOTP, nil +} + +// // Verify the token based on the prover secret key. // It will return true if the token matched, otherwise it will return false. // @@ -107,7 +125,7 @@ func (p *Protocol) generateWithTimestamp(mac hash.Hash, time int64) ( ) { steps := int64((float64(time) / float64(p.timeStep))) - msg := fmt.Sprintf("%016x", steps) + msg := fmt.Sprintf("%016X", steps) msgb, err := hex.DecodeString(msg) if err != nil { return "", err |
