Browse Source

Don't use custom PBKDF2 function (#3952)

Instead, use golang.org/x/crypto/pbkdf2
pull/3781/merge
leonklingele 8 years ago committed by 无闻
parent
commit
7cb440273c
  1. 4
      models/user.go
  2. 41
      modules/base/tool.go

4
models/user.go

@ -32,6 +32,8 @@ import (
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/markdown" "github.com/gogits/gogs/modules/markdown"
"github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/modules/setting"
"golang.org/x/crypto/pbkdf2"
) )
type UserType int type UserType int
@ -315,7 +317,7 @@ func (u *User) NewGitSig() *git.Signature {
// EncodePasswd encodes password to safe format. // EncodePasswd encodes password to safe format.
func (u *User) EncodePasswd() { func (u *User) EncodePasswd() {
newPasswd := base.PBKDF2([]byte(u.Passwd), []byte(u.Salt), 10000, 50, sha256.New) newPasswd := pbkdf2.Key([]byte(u.Passwd), []byte(u.Salt), 10000, 50, sha256.New)
u.Passwd = fmt.Sprintf("%x", newPasswd) u.Passwd = fmt.Sprintf("%x", newPasswd)
} }

41
modules/base/tool.go

@ -5,14 +5,12 @@
package base package base
import ( import (
"crypto/hmac"
"crypto/md5" "crypto/md5"
"crypto/rand" "crypto/rand"
"crypto/sha1" "crypto/sha1"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"hash"
"html/template" "html/template"
"math" "math"
"math/big" "math/big"
@ -110,45 +108,6 @@ func randomInt(max *big.Int) (int, error) {
return int(rand.Int64()), nil 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 // verify time limit code
func VerifyTimeLimitCode(data string, minutes int, code string) bool { func VerifyTimeLimitCode(data string, minutes int, code string) bool {
if len(code) <= 18 { if len(code) <= 18 {

Loading…
Cancel
Save