-
Notifications
You must be signed in to change notification settings - Fork 276
/
2fa.go
40 lines (34 loc) · 766 Bytes
/
2fa.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package base64Captcha
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base32"
"encoding/binary"
"strings"
"time"
"unicode"
)
const counterLen = 20
func noSpace(r rune) rune {
if unicode.IsSpace(r) {
return -1
}
return r
}
func decodeKey(key string) ([]byte, error) {
return base32.StdEncoding.DecodeString(strings.ToUpper(key))
}
func hotp(key []byte, counter uint64, digits int) int {
h := hmac.New(sha1.New, key)
binary.Write(h, binary.BigEndian, counter)
sum := h.Sum(nil)
v := binary.BigEndian.Uint32(sum[sum[len(sum)-1]&0x0F:]) & 0x7FFFFFFF
d := uint32(1)
for i := 0; i < digits && i < 8; i++ {
d *= 10
}
return int(v % d)
}
func totp(key []byte, t time.Time, digits int) int {
return hotp(key, uint64(t.UnixNano())/30e9, digits)
}