mirror of
https://github.com/passbolt/go-passbolt.git
synced 2025-05-10 01:48:22 +00:00
add totp generator from:
https://github.com/yitsushi/totp-cli/blob/master/security/otp.go
This commit is contained in:
parent
f01926b1c5
commit
663f5f6b76
1 changed files with 60 additions and 0 deletions
60
helper/totp.go
Normal file
60
helper/totp.go
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package helper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/base32"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
mask1 = 0xf
|
||||||
|
mask2 = 0x7f
|
||||||
|
mask3 = 0xff
|
||||||
|
timeSplitInSeconds = 30
|
||||||
|
shift24 = 24
|
||||||
|
shift16 = 16
|
||||||
|
shift8 = 8
|
||||||
|
codeLength = 6
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenerateOTPCode generates a 6 digit TOTP from the secret Token.
|
||||||
|
func GenerateOTPCode(token string, when time.Time) (string, error) {
|
||||||
|
timer := uint64(math.Floor(float64(when.Unix()) / float64(timeSplitInSeconds)))
|
||||||
|
// Remove spaces, some providers are giving us in a readable format
|
||||||
|
// so they add spaces in there. If it's not removed while pasting in,
|
||||||
|
// remove it now.
|
||||||
|
token = strings.Replace(token, " ", "", -1)
|
||||||
|
|
||||||
|
// It should be uppercase always
|
||||||
|
token = strings.ToUpper(token)
|
||||||
|
|
||||||
|
secretBytes, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(token)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Decoding token string: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := make([]byte, 8)
|
||||||
|
mac := hmac.New(sha1.New, secretBytes)
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint64(buf, timer)
|
||||||
|
_, _ = mac.Write(buf)
|
||||||
|
sum := mac.Sum(nil)
|
||||||
|
|
||||||
|
// http://tools.ietf.org/html/rfc4226#section-5.4
|
||||||
|
offset := sum[len(sum)-1] & mask1
|
||||||
|
value := int64(((int(sum[offset]) & mask2) << shift24) |
|
||||||
|
((int(sum[offset+1] & mask3)) << shift16) |
|
||||||
|
((int(sum[offset+2] & mask3)) << shift8) |
|
||||||
|
(int(sum[offset+3]) & mask3))
|
||||||
|
|
||||||
|
modulo := int32(value % int64(math.Pow10(codeLength)))
|
||||||
|
|
||||||
|
format := fmt.Sprintf("%%0%dd", codeLength)
|
||||||
|
|
||||||
|
return fmt.Sprintf(format, modulo), nil
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue