Skip to content

Commit

Permalink
Use cryptoHash instead of hash for passwords. Currently using 200,000…
Browse files Browse the repository at this point in the history
… rounds. Fix error in salt generation.
  • Loading branch information
Rob Archibald committed Jan 15, 2017
1 parent 27a190f commit 354a9b8
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
6 changes: 3 additions & 3 deletions authStore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ func TestAuthStoreEndToEnd(t *testing.T) {

// create profile
err = s.createProfile("fullName", "company", "password", "picturePath")
expectedPassword := encodeToString(hash([]byte("password")))
if err != nil || len(b.Users) != 1 || len(b.Sessions) != 1 || len(b.Logins) != 1 || b.Logins[0].LoginID != 1 || b.Logins[0].UserID != 1 || b.Logins[0].ProviderKey != expectedPassword {
t.Fatal("expected valid user, login and session", b.Logins[0], expectedPassword, b.Logins[0].ProviderKey)
hashErr := cryptoHashEquals("password", b.Logins[0].ProviderKey)
if err != nil || len(b.Users) != 1 || len(b.Sessions) != 1 || len(b.Logins) != 1 || b.Logins[0].LoginID != 1 || b.Logins[0].UserID != 1 || hashErr != nil {
t.Fatal("expected valid user, login and session", b.Logins[0], b.Logins[0].ProviderKey, hashErr)
}

// decode session cookie
Expand Down
2 changes: 1 addition & 1 deletion backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func (b *MockBackend) InvalidateRememberMe(selector string) error {
}

func loginSuccess() *LoginReturn {
return &LoginReturn{&UserLogin{LoginID: 1, ProviderKey: "zVNfmBbTwQZwyMsAizV1Guh_j7kcFbyG7-LRJeeJfXc="}, nil} // hash of "correctPassword"
return &LoginReturn{&UserLogin{LoginID: 1, ProviderKey: "$6$rounds=200000$pYt48w3PgDcRoCMx$sxbuADDhNI9nNe35HcrFYW7vpWLLMNiPBKcbqOgaRxTBYE8hePJWvmuN9dp.783JmDZBhDJRG956Wc/fzghhh."}, nil} // cryptoHash of "correctPassword"
}

func loginErr() *LoginReturn {
Expand Down
28 changes: 23 additions & 5 deletions cryptoStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"crypto/subtle"
"encoding/base64"
"errors"
"fmt"
"github.com/kless/osutil/user/crypt/sha512_crypt"
"math/big"
)

var errHashNotEqual = errors.New("input string does not match the supplied hash")
Expand Down Expand Up @@ -78,8 +80,22 @@ func generateRandomBytes(n int) ([]byte, error) {
return b, nil
}

func getRandomSalt(length, iterations int) (string, error) {
const letterBytes = `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\.`
b := make([]byte, length)
maxNum := big.NewInt(63)
for i := range b {
c, err := rand.Int(rand.Reader, maxNum)
if err != nil {
return "", err
}
b[i] = letterBytes[int(c.Int64())]
}
return fmt.Sprintf("$6$rounds=%d$%s", iterations, b), nil
}

func cryptoHashEquals(in string, hash string) error {
hashed, err := cryptoHashWSalt(in, []byte(hash)) // sha512_crypt will strip out salt from hash
hashed, err := cryptoHashWSalt(in, hash) // sha512_crypt will strip out salt from hash
if err != nil {
return err
}
Expand All @@ -90,14 +106,16 @@ func cryptoHashEquals(in string, hash string) error {
}

func cryptoHash(in string) (string, error) {
saltGenerator := sha512_crypt.GetSalt()
salt := saltGenerator.GenerateWRounds(16, 200000) // 16 character salt, 200k iterations
salt, err := getRandomSalt(16, 200000)
if err != nil {
return "", err
}
return cryptoHashWSalt(in, salt)
}

func cryptoHashWSalt(in string, salt []byte) (string, error) {
func cryptoHashWSalt(in, salt string) (string, error) {
gocrypt := sha512_crypt.New()
hash, err := gocrypt.Generate([]byte(in), salt)
hash, err := gocrypt.Generate([]byte(in), []byte(salt))
if err != nil {
return "", err
}
Expand Down

0 comments on commit 354a9b8

Please sign in to comment.