forked from all_user/stat_center
Initial commit
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
package googauth
|
||||
|
||||
import (
|
||||
"github.com/dgryski/dgoogauth"
|
||||
)
|
||||
|
||||
const windowSize = 30
|
||||
const htopWindowSize = 5
|
||||
|
||||
var HotpCfg = dgoogauth.OTPConfig{
|
||||
Secret: "MRSHM6LTMFYHAMJSGM2DKNQ=",
|
||||
HotpCounter: 1,
|
||||
WindowSize: htopWindowSize,
|
||||
}
|
||||
|
||||
func New(secret string, name string) string {
|
||||
cfg := &dgoogauth.OTPConfig{
|
||||
Secret: secret,
|
||||
WindowSize: windowSize,
|
||||
}
|
||||
return cfg.ProvisionURI(name)
|
||||
}
|
||||
|
||||
func Verify(secret string, pwd string) (bool, error) {
|
||||
cfg := &dgoogauth.OTPConfig{
|
||||
Secret: secret,
|
||||
WindowSize: windowSize,
|
||||
}
|
||||
return cfg.Authenticate(pwd)
|
||||
}
|
||||
|
||||
func VerifyHtop(cfg *dgoogauth.OTPConfig, authCode string, counter int) (bool, error) {
|
||||
return cfg.Authenticate(authCode)
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package googauth
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"fmt"
|
||||
"stat/common"
|
||||
"testing"
|
||||
|
||||
"github.com/dgryski/dgoogauth"
|
||||
)
|
||||
|
||||
func TestHotp(t *testing.T) {
|
||||
secret := base32.StdEncoding.EncodeToString([]byte(fmt.Sprintf("admin%s", common.RandStr(10))))
|
||||
fmt.Printf(secret)
|
||||
//d := int64(rand.Intn(100000))
|
||||
//randstr := strconv.FormatInt(d, 10)
|
||||
//ra := strconv.FormatInt(120868, 10)
|
||||
////serc := NewHotp("MFSG22LOORUXAVTINJRFGZ2Q", randstr)
|
||||
//res, _ := VerifyHotp("MFSG22LOORUXAVTINJRFGZ2Q", ra)
|
||||
////fmt.Println(err)
|
||||
////fmt.Println(res)
|
||||
////fmt.Println(serc)
|
||||
//fmt.Println(res)
|
||||
//h := NewHOTP([]byte("abcdefghijk"), 6)
|
||||
//fmt.Println(h.GenerateCode())
|
||||
//fmt.Println(h)
|
||||
}
|
||||
|
||||
// func TestRandBase(t *testing.T) {
|
||||
|
||||
// for i := 0; i < 10; i++ {
|
||||
// tn := common.RandIntBase(1564, 1, 5000)
|
||||
// fmt.Println(tn)
|
||||
// h := NewHOTP([]byte("abcdefghijk"), 5)
|
||||
// code := h.GenerateCode(uint64(tn))
|
||||
// res := h.VerifyCode(code, uint64(tn))
|
||||
// fmt.Println(res)
|
||||
// }
|
||||
// }
|
||||
|
||||
//func TestCode(t *testing.T) {
|
||||
// for i := 0; i < 10; i++ {
|
||||
// count := common.RandIntBase(12345678, 1, 99999999)
|
||||
// fmt.Println(count)
|
||||
// dd := dgoogauth.ComputeCode("MRSHM6LTMFYHAMJSGM2DKNQ=", 1234)
|
||||
// authCode := strconv.FormatInt(int64(dd), 10)
|
||||
// re, _ := VerifyHotp("MRSHM6LTMFYHAMJSGM2DKNQ=", authCode, 1234)
|
||||
// fmt.Println(re)
|
||||
// }
|
||||
//}
|
||||
|
||||
func TestHotpCode(t *testing.T) {
|
||||
|
||||
var HotpCfg = dgoogauth.OTPConfig{
|
||||
Secret: "MRSHM6LTMFYHAMJSGM2DKNQ=",
|
||||
HotpCounter: 1,
|
||||
WindowSize: 3,
|
||||
}
|
||||
|
||||
var cotp dgoogauth.OTPConfig
|
||||
|
||||
// reuse our test values from above
|
||||
// perhaps create more?
|
||||
cotp.Secret = "2SH3V3GDW7ZNMGYE"
|
||||
cotp.HotpCounter = 1
|
||||
cotp.WindowSize = 10
|
||||
|
||||
//var counterCodes = []struct {
|
||||
// code int
|
||||
// result bool
|
||||
// counter int
|
||||
//}{
|
||||
// { /* 1 */ 293240, true, 2}, // increments on success
|
||||
// { /* 1 */ 293240, false, 3}, // and failure
|
||||
// { /* 5 */ 932068, true, 6}, // inside of window
|
||||
// { /* 10 */ 481725, false, 7}, // outside of window
|
||||
// { /* 10 */ 481725, false, 8}, // outside of window
|
||||
// { /* 10 */ 481725, true, 11}, // now inside of window
|
||||
//}
|
||||
|
||||
//for _, s := range counterCodes {
|
||||
// authCode := strconv.FormatInt(int64(s.code), 10)
|
||||
// res, _ := cotp.Authenticate(authCode)
|
||||
// fmt.Println(res)
|
||||
//}
|
||||
for i := 0; i < 5; i++ {
|
||||
res, _ := VerifyHtop(&HotpCfg, "807708", 322904702)
|
||||
//res2, _ := cotp.Authenticate("293240")
|
||||
fmt.Println(res)
|
||||
//fmt.Println(res2)
|
||||
//fmt.Println(cotp)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package googauth
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// HOTP implementation
|
||||
type HOTP struct {
|
||||
secret []byte
|
||||
digits int
|
||||
}
|
||||
|
||||
// At generate code
|
||||
func (h HOTP) At(counter uint64) string {
|
||||
counterBytes := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(counterBytes, counter)
|
||||
hash := hmac.New(sha1.New, h.secret)
|
||||
hash.Write(counterBytes)
|
||||
hs := hash.Sum(nil)
|
||||
offset := hs[19] & 0x0f
|
||||
binCodeBytes := make([]byte, 4)
|
||||
binCodeBytes[0] = hs[offset] & 0x7f
|
||||
binCodeBytes[1] = hs[offset+1] & 0xff
|
||||
binCodeBytes[2] = hs[offset+2] & 0xff
|
||||
binCodeBytes[3] = hs[offset+3] & 0xff
|
||||
binCode := binary.BigEndian.Uint32(binCodeBytes)
|
||||
mod := uint32(1)
|
||||
for i := 0; i < h.digits; i++ {
|
||||
mod *= 10
|
||||
}
|
||||
code := binCode % mod
|
||||
codeString := strconv.FormatUint(uint64(code), 10)
|
||||
if len(codeString) < h.digits {
|
||||
paddingByteLength := h.digits - len(codeString)
|
||||
paddingBytes := make([]byte, paddingByteLength)
|
||||
for i := 0; i < paddingByteLength; i++ {
|
||||
paddingBytes[i] = '0'
|
||||
}
|
||||
codeString = string(paddingBytes) + codeString
|
||||
}
|
||||
return codeString
|
||||
}
|
||||
|
||||
// Verify verify OTP code
|
||||
func (h HOTP) VerifyCode(code string, counter uint64) bool {
|
||||
realCode := h.At(counter)
|
||||
if realCode == code {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Verify verify OTP code
|
||||
func (h HOTP) GenerateCode(counter uint64) string {
|
||||
return h.At(counter)
|
||||
}
|
||||
|
||||
// NewHOTP generate new HOTP instance
|
||||
func NewHOTP(secret []byte, digits int) (h *HOTP) {
|
||||
h = new(HOTP)
|
||||
h.secret = secret
|
||||
h.digits = digits
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user