44 lines
980 B
Go
44 lines
980 B
Go
package otp
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/rand"
|
|
"crypto/sha1"
|
|
"encoding/base32"
|
|
)
|
|
|
|
func generateRandomSecret(size int, encodeToBase32 bool) string {
|
|
alphanum := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
|
var bytes = make([]byte, size)
|
|
rand.Read(bytes)
|
|
for i, b := range bytes {
|
|
bytes[i] = alphanum[b%byte(len(alphanum))]
|
|
}
|
|
if encodeToBase32 {
|
|
return base32.StdEncoding.EncodeToString(bytes)
|
|
}
|
|
return string(bytes)
|
|
}
|
|
|
|
func counterToBytes(counter uint64) (text []byte) {
|
|
text = make([]byte, 8)
|
|
for i := 7; i >= 0; i-- {
|
|
text[i] = byte(counter & 0xff)
|
|
counter = counter >> 8
|
|
}
|
|
return
|
|
}
|
|
|
|
func hmacSHA1(key, text []byte) []byte {
|
|
H := hmac.New(sha1.New, key)
|
|
H.Write([]byte(text))
|
|
return H.Sum(nil)
|
|
}
|
|
|
|
func truncate(hash []byte) int {
|
|
offset := int(hash[len(hash)-1] & 0xf)
|
|
return ((int(hash[offset]) & 0x7f) << 24) |
|
|
((int(hash[offset+1] & 0xff)) << 16) |
|
|
((int(hash[offset+2] & 0xff)) << 8) |
|
|
(int(hash[offset+3]) & 0xff)
|
|
}
|