0 Star 1 Fork 0

有点心急 / gotls

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
otp.go 2.54 KB
一键复制 编辑 原始数据 按行查看 历史
有点心急 提交于 2024-05-04 01:31 . 24.05.04
package totpT
import (
"crypto/hmac"
"crypto/sha512"
"encoding/binary"
"errors"
"hash"
"math"
"math/rand"
"strconv"
"time"
"gitee.com/Jiudan0905/go-tools/logT"
)
func HOTP(h func() hash.Hash, key []byte, count uint64, digits int) (string, error) {
if digits < 1 {
return "", errors.New("数字值必须大于 0, 建议至少为 6 位数字的值")
}
hash := hmacGenerator(h, key, count)
offset := hash[len(hash)-1] & 0xf
dbc := hash[offset : offset+4]
dbc[0] = dbc[0] & 0x7f
code := binary.BigEndian.Uint32(dbc)
otp := code % uint32(math.Pow10(digits))
value := strconv.Itoa(int(otp))
for i := 0; i < digits-len(value); i++ {
value = "0" + value
}
return value, nil
}
func TOTP(h func() hash.Hash, secret []byte, t time.Time, interval int, digits int) (string, error) {
if interval < 1 {
return "", errors.New("间隔值必须大于 0, 建议默认为 30")
}
count := numTimeSteps(t, interval, 0)
return HOTP(h, secret, count, digits)
}
// GenTotpToken 获取数字密钥
func GenTotpToken(secret string) (string, error) {
ti := time.Now().Unix()
t := time.Unix(ti, 0)
totp, err := TOTP(func() hash.Hash {
return sha512.New()
}, []byte(secret), t, 30, 7)
if err != nil {
logT.Error(err.Error())
return "", err
}
totp64, err := strconv.ParseInt(totp, 10, 64)
if err != nil {
logT.Error(err.Error())
}
return GenRandomToken(totp64), nil
}
// GenRandomToken 获取加密密钥
func GenRandomToken(totp int64) string {
token := make([]byte, 6)
LetterBytes := "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
rand.Seed(totp)
for i := range token {
token[i] = LetterBytes[rand.Intn(len(LetterBytes))]
}
return string(token)
}
// GetTotpToken 忽略错误,直接获取token
func GetTotpToken(secret string) string {
token, err := GenTotpToken(secret)
if err != nil {
logT.Error(err.Error())
return "ERROR-TOKEN"
}
return token
}
// VerifyTotpToken 验证token
func VerifyTotpToken(secret string, token string) (ok bool) {
// 验证Token是否正确
realToken := GetTotpToken(secret)
if token != realToken {
return false
}
return true
}
// numTimeSteps 初始计数器时间 T0 和当前 Unix 时间之间的时间步长数
func numTimeSteps(t time.Time, interval int, t0 int64) uint64 {
return uint64(math.Floor(float64(t.Unix()-t0) / float64(interval)))
}
// hmacGenerator 使用指定的算法生成密钥和计数的 HMAC。
func hmacGenerator(h func() hash.Hash, key []byte, count uint64) []byte {
mac := hmac.New(h, key)
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, count)
mac.Write(buf)
return mac.Sum(nil)
}
Go
1
https://gitee.com/ydxj/gotls.git
git@gitee.com:ydxj/gotls.git
ydxj
gotls
gotls
v0.0.4

搜索帮助