| 123456789101112131415161718192021222324252627282930 |
- package fwh_pro
- import (
- "crypto/hmac"
- "crypto/sha1"
- "encoding/base32"
- "encoding/binary"
- "fmt"
- "strings"
- "time"
- )
- // generateTOTP implements RFC 6238 with the common SHA-1, 6-digit, 30-second profile.
- func generateTOTP(secret string, now time.Time) (string, error) {
- secret = strings.ToUpper(strings.Join(strings.Fields(secret), ""))
- secret = strings.TrimRight(secret, "=")
- key, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(secret)
- if err != nil || len(key) == 0 {
- return "", fmt.Errorf("invalid FWH TOTP secret: expected a Base32 key")
- }
- var counter [8]byte
- binary.BigEndian.PutUint64(counter[:], uint64(now.Unix()/30))
- mac := hmac.New(sha1.New, key)
- _, _ = mac.Write(counter[:])
- digest := mac.Sum(nil)
- offset := digest[len(digest)-1] & 0x0f
- value := binary.BigEndian.Uint32(digest[offset:offset+4]) & 0x7fffffff
- return fmt.Sprintf("%06d", value%1000000), nil
- }
|