Password hashing
dygo g security and dygo g auth write a password.go file into the generated package. It uses only the standard library: PBKDF2-HMAC-SHA256 with 600,000 iterations, as OWASP advises, and a random 16 byte salt.
// passwordIterations follows the OWASP advice for PBKDF2-HMAC-SHA256.const passwordIterations = 600_000
// HashPassword returns "pbkdf2-sha256$<iterations>$<salt>$<hash>".func HashPassword(password string) (string, error) { salt := make([]byte, 16) if _, err := rand.Read(salt); err != nil { return "", err } key, err := pbkdf2.Key(sha256.New, password, salt, passwordIterations, 32) if err != nil { return "", err } enc := base64.RawStdEncoding return fmt.Sprintf("pbkdf2-sha256$%d$%s$%s", passwordIterations, enc.EncodeToString(salt), enc.EncodeToString(key)), nil}CheckPassword(hash, password)compares in constant time.NeedsRehash(hash)reports a hash made with fewer iterations. The generated login then saves a new hash, so raisingpasswordIterationsupgrades users as they sign in.- Login takes the same time for an unknown email and for a wrong password.
The authentication page covers the rest of the generated package.