From d771e978a108517ca5833b5e2f17b45e2d7dc6ca Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 15 Dec 2016 09:24:27 +0800 Subject: [PATCH] Don't use custom PBKDF2 function (#382) --- models/user.go | 3 +- modules/base/tool.go | 41 ----------- vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go | 77 +++++++++++++++++++++ vendor/vendor.json | 6 ++ 4 files changed, 85 insertions(+), 42 deletions(-) create mode 100644 vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go diff --git a/models/user.go b/models/user.go index 40afc4849..a9a7ba594 100644 --- a/models/user.go +++ b/models/user.go @@ -25,6 +25,7 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" "github.com/nfnt/resize" + "golang.org/x/crypto/pbkdf2" "code.gitea.io/git" api "code.gitea.io/sdk/gitea" @@ -361,7 +362,7 @@ func (u *User) NewGitSig() *git.Signature { // EncodePasswd encodes password to safe format. 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) } diff --git a/modules/base/tool.go b/modules/base/tool.go index 981f89b6a..e41d1ca46 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -5,14 +5,12 @@ package base import ( - "crypto/hmac" "crypto/md5" "crypto/rand" "crypto/sha1" "encoding/base64" "encoding/hex" "fmt" - "hash" "html/template" "math" "net/http" @@ -97,45 +95,6 @@ func GetRandomString(n int, alphabets ...byte) string { return string(bytes) } -// PBKDF2 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] -} - // VerifyTimeLimitCode verify time limit code func VerifyTimeLimitCode(data string, minutes int, code string) bool { if len(code) <= 18 { diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go new file mode 100644 index 000000000..593f65300 --- /dev/null +++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go @@ -0,0 +1,77 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC +2898 / PKCS #5 v2.0. + +A key derivation function is useful when encrypting data based on a password +or any other not-fully-random data. It uses a pseudorandom function to derive +a secure encryption key based on the password. + +While v2.0 of the standard defines only one pseudorandom function to use, +HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved +Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To +choose, you can pass the `New` functions from the different SHA packages to +pbkdf2.Key. +*/ +package pbkdf2 // import "golang.org/x/crypto/pbkdf2" + +import ( + "crypto/hmac" + "hash" +) + +// Key derives a key from the password, salt and iteration count, returning a +// []byte of length keylen that can be used as cryptographic key. The key is +// derived based on the method described as PBKDF2 with the HMAC variant using +// the supplied hash function. +// +// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you +// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by +// doing: +// +// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New) +// +// Remember to get a good random salt. At least 8 bytes is recommended by the +// RFC. +// +// Using a higher iteration count will increase the cost of an exhaustive +// search but will also make derivation proportionally slower. +func Key(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] +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 1c1b0acdf..50447e4bf 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -872,6 +872,12 @@ "revision": "9477e0b78b9ac3d0b03822fd95422e2fe07627cd", "revisionTime": "2016-10-31T15:37:30Z" }, + { + "checksumSHA1": "1MGpGDQqnUoRpv7VEcQrXOBydXE=", + "path": "golang.org/x/crypto/pbkdf2", + "revision": "8e06e8ddd9629eb88639aba897641bff8031f1d3", + "revisionTime": "2016-09-10T18:59:01Z" + }, { "checksumSHA1": "LlElMHeTC34ng8eHzjvtUhAgrr8=", "path": "golang.org/x/crypto/ssh",