Change default password hashing algorithm to bcrypt.

Now that we limit the number of concurrent password hashing
operations, it is safe to use an algorithm that uses a fait
amount of memory.  We use strength 8, which is below the recommended
default, in order to keep password hashing time below 25ms.
This commit is contained in:
Juliusz Chroboczek
2025-01-20 16:47:49 +01:00
parent 7a99668c6d
commit 910b60f3c4
3 changed files with 9 additions and 17 deletions
+2 -3
View File
@@ -280,12 +280,11 @@ func hashPasswordCmd(cmdname string, args []string) {
os.Args[0], cmdname, os.Args[0], cmdname,
) )
cmd.StringVar(&password, "password", "", "new `password`") cmd.StringVar(&password, "password", "", "new `password`")
cmd.StringVar(&algorithm, "type", "pbkdf2", cmd.StringVar(&algorithm, "type", "bcrypt",
"password `type`") "password `type`")
cmd.IntVar(&iterations, "iterations", 4096, cmd.IntVar(&iterations, "iterations", 4096,
"`number` of iterations (pbkdf2)") "`number` of iterations (pbkdf2)")
cmd.IntVar(&cost, "cost", bcrypt.DefaultCost, cmd.IntVar(&cost, "cost", 8, "`cost` (bcrypt)")
"`cost` (bcrypt)")
cmd.IntVar(&length, "key", 32, "key `length` (pbkdf2)") cmd.IntVar(&length, "key", 32, "key `length` (pbkdf2)")
cmd.IntVar(&saltlen, "salt", 8, "salt `length` (pbkdf2)") cmd.IntVar(&saltlen, "salt", 8, "salt `length` (pbkdf2)")
cmd.Parse(args) cmd.Parse(args)
+6 -13
View File
@@ -2,9 +2,7 @@ package webserver
import ( import (
"crypto/rand" "crypto/rand"
"crypto/sha256"
"encoding/base64" "encoding/base64"
"encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
"io" "io"
@@ -13,7 +11,7 @@ import (
"os" "os"
"strings" "strings"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/bcrypt"
"github.com/jech/galene/group" "github.com/jech/galene/group"
"github.com/jech/galene/stats" "github.com/jech/galene/stats"
@@ -407,21 +405,16 @@ func passwordHandler(w http.ResponseWriter, r *http.Request, g, user string, wil
if done { if done {
return return
} }
salt := make([]byte, 8) key, err := bcrypt.GenerateFromPassword(body, 8)
_, err := rand.Read(salt)
if err != nil { if err != nil {
httpError(w, err) httpError(w, err)
return return
} }
iterations := 4096
key := pbkdf2.Key(body, salt, iterations, 32, sha256.New) k := string(key)
encoded := hex.EncodeToString(key)
pw := group.Password{ pw := group.Password{
Type: "pbkdf2", Type: "bcrypt",
Hash: "sha-256", Key: &k,
Key: &encoded,
Salt: hex.EncodeToString(salt),
Iterations: iterations,
} }
err = group.SetUserPassword(g, user, wildcard, pw) err = group.SetUserPassword(g, user, wildcard, pw)
if err != nil { if err != nil {
+1 -1
View File
@@ -241,7 +241,7 @@ func TestApi(t *testing.T) {
t.Errorf("Users: %#v", desc.Users) t.Errorf("Users: %#v", desc.Users)
} }
if desc.Users["jch"].Password.Type != "pbkdf2" { if desc.Users["jch"].Password.Type != "bcrypt" {
t.Errorf("Password.Type: %v", desc.Users["jch"].Password.Type) t.Errorf("Password.Type: %v", desc.Users["jch"].Password.Type)
} }