summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <m.shulhan@gmail.com>2020-12-23 21:58:27 +0700
committerShulhan <m.shulhan@gmail.com>2020-12-23 21:58:27 +0700
commitae0e03ebec6061d5a85ebe54ac4c77cef18f1972 (patch)
tree67b3a21c5fb36ccf2b42579b77ff1f5a49f5f806
parentf9804fe2bce4ff427391c433c93f9f70381ec57d (diff)
downloadpakakeh.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.go19
-rw-r--r--lib/totp/totp.go20
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