password

package
v0.0.0-...-ba7cdbd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 10, 2014 License: MPL-2.0 Imports: 13 Imported by: 0

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 gnd.la/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

View Source
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
)
View Source
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

View Source
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

func HashNamed(name string) (Hash, error)

HashNamed returns the hash with the given name. If no hash with that name is found, an error is returned.

func (Hash) Available

func (h Hash) Available() bool

Available returns if the given hash function is available at runtime.

func (Hash) Hash

func (h Hash) Hash(salt string, plain string, rounds int) string

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.

func (Hash) Name

func (h Hash) Name() string

Name returns the name of the hash.

func (Hash) New

func (h Hash) New() hash.Hash

New returns a new hash.Hash which calculates the given hash function.

func (Hash) RawHash

func (h Hash) RawHash(salt string, plain string, rounds int) []byte

Hash returns the result of hashing the given salt and plaintext with the given number of rounds. The result is the hash as a []byte. See also Hash.Hash.

func (Hash) Size

func (h Hash) Size() int

Size returns the size in bytes of the hash output.

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

func New(plain string) Password

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"
	"gnd.la/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

func NewOptions(plain string, opts *Options) Password

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

func (p Password) Check(plain string) error

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"
	"gnd.la/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) Hash

func (p Password) Hash() (Hash, error)

Hash returns the Hash used to encode the password.

func (Password) IsValid

func (p Password) IsValid() bool

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

func (p Password) Matches(plain string) bool

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.

func (Password) Rounds

func (p Password) Rounds() (int, error)

Rounds returns the number of PBKDF2 rounds used to encode this password.

func (Password) Salt

func (p Password) Salt() string

Salt returns the salt used to encode the password.

func (Password) String

func (p Password) String() string

String returns the password string as hash:rounds:salt:hex(hash)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL