|
@@ -5,14 +5,12 @@
|
|
|
package base
|
|
|
|
|
|
import (
|
|
|
- "crypto/hmac"
|
|
|
"crypto/md5"
|
|
|
"crypto/rand"
|
|
|
"crypto/sha1"
|
|
|
"encoding/base64"
|
|
|
"encoding/hex"
|
|
|
"fmt"
|
|
|
- "hash"
|
|
|
"html/template"
|
|
|
"math"
|
|
|
"math/big"
|
|
@@ -110,45 +108,6 @@ func randomInt(max *big.Int) (int, error) {
|
|
|
return int(rand.Int64()), nil
|
|
|
}
|
|
|
|
|
|
-// http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto
|
|
|
-// FIXME: use https://godoc.org/golang.org/x/crypto/pbkdf2?
|
|
|
-func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
|
|
|
- prf := hmac.New(h, password)
|
|
|
- hashLen := prf.Size()
|
|
|
- numBlocks := (keyLen + hashLen - 1) / hashLen
|
|
|
-
|
|
|
- var buf [4]byte
|
|
|
- dk := make([]byte, 0, numBlocks*hashLen)
|
|
|
- U := make([]byte, hashLen)
|
|
|
- for block := 1; block <= numBlocks; block++ {
|
|
|
- // N.B.: || means concatenation, ^ means XOR
|
|
|
- // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
|
|
|
- // U_1 = PRF(password, salt || uint(i))
|
|
|
- prf.Reset()
|
|
|
- prf.Write(salt)
|
|
|
- buf[0] = byte(block >> 24)
|
|
|
- buf[1] = byte(block >> 16)
|
|
|
- buf[2] = byte(block >> 8)
|
|
|
- buf[3] = byte(block)
|
|
|
- prf.Write(buf[:4])
|
|
|
- dk = prf.Sum(dk)
|
|
|
- T := dk[len(dk)-hashLen:]
|
|
|
- copy(U, T)
|
|
|
-
|
|
|
- // U_n = PRF(password, U_(n-1))
|
|
|
- for n := 2; n <= iter; n++ {
|
|
|
- prf.Reset()
|
|
|
- prf.Write(U)
|
|
|
- U = U[:0]
|
|
|
- U = prf.Sum(U)
|
|
|
- for x := range U {
|
|
|
- T[x] ^= U[x]
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return dk[:keyLen]
|
|
|
-}
|
|
|
-
|
|
|
// verify time limit code
|
|
|
func VerifyTimeLimitCode(data string, minutes int, code string) bool {
|
|
|
if len(code) <= 18 {
|