Documentation ¶
Overview ¶
Package password contains functions for securely storing and checking passwords.
Passwords are encoded using a per-password salt and then hashed using PBKDF2 with the chosen algorithm (sha256 by default). Password provides the Check() method for verifying that the given plaintext matches the encoded password. This method is not vulnerable to timing attacks.
Password objects can be stored directly by Gondola's ORM.
// "foo" is the username, "bar" is the password. type User struct { UserId int64 `orm:",primary_key,auto_increment"` Username string Password password.Password } // Creating a new user user := &User{Username:"foo", Password: password.New("bar")} // o is a gondola/orm.Orm object o.MustSave(user) // Signin in an existing user var user *User if err := o.One(orm.Eq("Username", "foo"), &user); err == nil { if user.Password.Check("bar") == nil { // user has provided the correct password } }
Password objects can also be stored on anything that accepts strings. See the examples to learn how to manually store and verify a password.
Index ¶
Examples ¶
Constants ¶
const ( // SHA1 hash - 160 bits SHA1 = Hash(crypto.SHA1) // SHA224 hash - 224 bits SHA224 = Hash(crypto.SHA224) // SHA256 hash - 256 bits SHA256 = Hash(crypto.SHA256) // SHA384 hash - 384 bits SHA384 = Hash(crypto.SHA384) // SHA512 hash - 512 bits SHA512 = Hash(crypto.SHA512) // DefaultHash is the hash used by default, currently SHA256. DefaultHash = SHA256 )
const ( // MaxPasswordLength is the maximum password length. Trying to create // or verify a password longer than this will cause an error. This // is a measure against DoS attacks. MaxPasswordLength = 8192 // DefaultRounds is the number of PBKDF2 rounds used when creating a new password. // Altering this number won't break already generated and stored passwords, // since they store the number of rounds they were created with. DefaultRounds = 4096 )
Variables ¶
var ( // ErrNoMatch means the password provided in Check() does not match the stored one. ErrNoMatch = errors.New("password does not match") // ErrInvalidFieldCount means the password does not have the required // number of fields. ErrInvalidFieldCount = errors.New("encoded password does not have 4 fields") // ErrInvalidRoundCount means the number of rounds stored in the password // is not a positive integer. ErrInvalidRoundCount = errors.New("invalid number of rounds") // ErrInvalidSaltLength means the salt stored with the password does // not match the password's hash key size. ErrInvalidSaltLength = errors.New("salt does not have the same length as the hash output") // ErrInvalidHashedLength the hash output stored in the password does // no match the password's hash output size. ErrInvalidHashedLength = errors.New("hashed password does not have the same length as the hash output") // ErrInvalidHex means the encoded password value is not properly // encoded as hexadecimal. ErrInvalidHex = errors.New("hashed password is not properly encoded") )
Functions ¶
This section is empty.
Types ¶
type Hash ¶
type Hash uint
Type Hash represents a hash algorithm for hashing passwords.
func HashNamed ¶
HashNamed returns the hash with the given name. If no hash with that name is found, an error is returned.
func (Hash) Hash ¶
Hash returns the result of hashing the given salt and plaintext with the given number of rounds. The result is a hex encoded string. See also Hash.RawHash.
type Options ¶
type Options struct { // The Hash to use for hashing the Password. If this // field is zero, DefaultHash is used. Hash Hash // Rounds is the number of PBKDF2 iterations used // for the password. If this field is <= 0, DefaultRounds // is used instead. Rounds int }
Options specify the Password options when creating one from its plaintext.
type Password ¶
type Password string
Password represents an encoded password, which can be stored as a string and then used to verify if the user provided password matches the stored one.
func New ¶
New returns a new Password hashed using DefaultHash with DefaultRounds. Most users would want to use this function to create a Password from a plaintext string. For advanced uses, see NewOptions.
Example ¶
package main import ( "fmt" "gondola/crypto/password" ) func main() { // Provided by the user, usually at registration. plain := "alberto" // p contains the encoded password, which can // be stored in the database. p := password.New(plain) // This prints the encoded password. fmt.Println(p) // This will print the same as the previous line // but its type will be string. It might be useful // for some storage drivers that expect values of // type string. fmt.Println(p.String()) }
Output:
func NewOptions ¶
NewOptions returns a password hashed with the given hash and rounds. If the hash is not available or not valid, it will panic. If Hash or Rounds are not provided, DefaultHash and DefaultRounds, respectivelly, are used.
func (Password) Check ¶
Check returns nil if the password could be verified without any errors and it matches the provided plain text password. This function performs a constant time comparison, so it's not vulnerable to timing attacks.
Example ¶
package main import ( "fmt" "gondola/crypto/password" ) func main() { // This will usually come from the database. In this case, the encoded // password is "gondola". encoded := "sha1:4096:JJf2f46fmbw06LwXJ308:9b4d23006b93e1d6bb052c1545d9532d1433736b" // This will usually come from a form, filled in by the user for signing in. plain := "gondola" p := password.Password(encoded) if p.Check(plain) == nil { // Plaintext password matches the stored one. fmt.Println("Password is", plain) } }
Output: Password is gondola
func (Password) IsValid ¶
IsValid returns true iff the password is a correctly encoded password. This means it has a hash that is available and the salt and hashed data have the same length as the hash output.
func (Password) Matches ¶
Matches is a shorthand for Check(plain) == nil. Id est, if returns true iff the password is correctly encoded and the provided plain password matches the encoded one.