argon2

package module
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Apr 5, 2020 License: MIT Imports: 8 Imported by: 4

README

argon2-hashing

GoDoc Build Status Go Report Card codecov

argon2-hashing provides a light wrapper around Go's argon2 package. Argon2 was the winner of the Password Hashing Competition that makes it easier to securely derive strong keys from weak inputs (i.e. user passwords).

With this library you can:

  • Generate a argon2 derived key with a crytographically secure salt and default parameters.
  • Tune argon2 with you own parameters based of you hardware configuration.
  • Compare a derived key with the possible cleartext equivalent (user password).

Currently supported only Argon2id function.

The API closely mirrors with Go's Bcrypt library and Alex Edwards simple-scrypt package.

Installation

With a Go modules:

go get -u github.com/andskur/argon2-hashing

Example

argon2-hashing doesn't try to re-invent the wheel or do anything "special". It wraps the argon2.IDKey function as thinly as possible, generates a crytographically secure salt for you using Go's crypto/rand package, and returns the derived key with the parameters prepended:

package main

import(
    "fmt"
    "log"

    "github.com/andskur/argon2-hashing"
)

func main() {
    // e.g. r.PostFormValue("password")
    passwordFromForm := "qwerty123"

    // Generates a derived key with default params
    hash, err := argon2.GenerateFromPassword([]byte(passwordFromForm), argon2.DefaultParams)
    if err != nil {
        log.Fatal(err)
    }

    // Print the derived key.
    fmt.Printf("%s\n", hash)

    // Uses the parameters from the existing derived key. Return an error if they don't match.
    err = argon2.CompareHashAndPassword(hash, []byte(passwordFromForm))
    if err != nil {
        log.Fatal(err)
    }
}

Argon2 introduction

The Argon2 algorithm accepts a number of configurable parameters:

  • Memory — The amount of memory used by the algorithm (in kibibytes).
  • Iterations — The number of iterations (or passes) over the memory.
  • Parallelism — The number of threads (or lanes) used by the algorithm.
  • Salt length — Length of the random salt. 16 bytes is recommended for password hashing.
  • Key length — Length of the generated key (or password hash). 16 bytes or more is recommended.
  • The memory and iterations parameters control the computational cost of hashing the password. The higher these figures are, the greater the cost of generating the hash. It also follows that the greater the cost will be for any attacker trying to guess the password.

But there's a balance that you need to strike. As you increase the cost, the time taken to generate the hash also increases. If you're generating the hash in response to a user action (like signing up or logging in to a website) then you probably want to keep the runtime to less than 500ms to avoid a negative user experience.

If the Argon2 algorithm is running on a machine with multiple cores, then one way to decrease the runtime without reducing the cost is to increase the parallelism parameter. This controls the number of threads that the work is spread across. There's an important thing to note here though: changing the value of the parallelism parameter changes the output of the algorithm. So — for example — running Argon2 with a parallelism parameter of 2 will result in a different password hash to running it with a parallelism parameter of 4.

Choosing Parameters

Picking the right parameters for Argon2 depends heavily on the machine that the algorithm is running on, and you'll probably need to do some experimentation in order to set them appropriately.

The recommended process for choosing the parameters can be paraphrased as follows:

  1. Set the parallelism and memory parameters to the largest amount you are willing to afford, bearing in mind that you probably don't want to max these out completely unless your machine is dedicated to password hashing.
  2. Increase the number of iterations until you reach your maximum runtime limit (for example, 500ms).
  3. If you're already exceeding the your maximum runtime limit with the number of iterations = 1, then you should reduce the memory parameter.

Thanks to

Authors

License

This project is licensed under the MIT License - see the LICENSE file for details

Documentation

Overview

Package argon2 provides a convenience wrapper around Go's argon2 package. Currently supported only Argon2id. Argon2 was the winner of the Password Hashing Competition that makes it easier to securely derive strong keys from weak inputs (i.e. user passwords). The package provides password generation, constant-time comparison and parameter upgrading for argon2 derived keys.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultParams = &Params{
	Memory:      64 * 1024,
	Iterations:  3,
	Parallelism: 2,
	SaltLength:  16,
	KeyLength:   32,
}

DefaultParams provides sensible default inputs into the argon2 function for interactive use. The default key length is 256 bits.

View Source
var ErrIncompatibleVersion = errors.New("argon2: incompatible version of argon2")

ErrIncompatibleVersion is returned when version of provided argon2 hash s incompatible with current argon2 algorithm

View Source
var ErrInvalidHash = errors.New("argon2: the encoded hash is not in the correct format")

ErrInvalidHash is returned when function failed to parse provided argon2 hash and/or given parameters.

View Source
var ErrInvalidParams = errors.New("argon2: the parameters provided are invalid")

ErrInvalidParams is returned when the cost parameters (N, r, p), salt length or derived key length are invalid.

View Source
var ErrMismatchedHashAndPassword = errors.New("argon2: the hashed password does not match the hash of the given password")

ErrMismatchedHashAndPassword is returned when a password (hashed) and given hash do not match.

Functions

func CompareHashAndPassword

func CompareHashAndPassword(hash, password []byte) error

CompareHashAndPassword compares a derived key with the possible cleartext equivalent. The parameters used in the provided derived key are used. The comparison performed by this function is constant-time. It returns nil on success, and an error if the derived keys do not match.

Example
// e.g. r.PostFormValue("password")
passwordFromForm := "qwerty123"

// e.g. hash from database
hash := "qwerty123"

// Check password with a hash. Return an error if they don't match
err := CompareHashAndPassword([]byte(hash), []byte(passwordFromForm))
if err != nil {
	log.Fatal(err)
}
// Do something next
Output:

func GenerateFromPassword

func GenerateFromPassword(password []byte, p *Params) ([]byte, error)

GenerateFromPassword returns the derived key of the password using the parameters provided. The parameters are prepended to the derived key and separated by the "$" character

Example
// e.g. r.PostFormValue("password")
passwordFromForm := "qwerty123"

// Generates a derived key with default params
hash, err := GenerateFromPassword([]byte(passwordFromForm), DefaultParams)
if err != nil {
	log.Fatal(err)
}

// Print the derived key - "argon2id$19$65536$3$2$R8kBdA675bqNJbhWntdlAA$X28Igb1N0MBO3IWOIPoS+JxLmhAx0KBUYe65BSEsMs8"
fmt.Printf("%s\n", hash)
Output:

func GenerateRandomBytes

func GenerateRandomBytes(n uint32) ([]byte, error)

GenerateRandomBytes returns securely generated random bytes. It will return an error if the system's secure random number generator fails to function correctly, in which case the caller should not continue.

Types

type Params

type Params struct {
	Memory      uint32 // The amount of memory used by the algorithm (kibibytes)
	Iterations  uint32 // The number of iterations (passes) over the memory
	Parallelism uint8  // The number of threads (lanes) used by the algorithm
	SaltLength  uint32 // Length of the random salt. 16 bytes is recommended for password hashing
	KeyLength   uint32 // Length of the generated key (password hash). 16 bytes or more is recommended
}

Params describes the input parameters to the argon2 key derivation function. The iterations parameter specifies the number of passes over the memory and the memory parameter specifies the size of the memory in KiB. For example memory=64*1024 sets the memory cost to ~64 MB. The number of parallelism can be adjusted to the number of available CPUs. The cost parameters should be increased as memory latency and CPU parallelism increases. Remember to get a good random salt.

func (*Params) Check

func (p *Params) Check() error

Check checks that the parameters are valid for input into the argon2 key derivation function.

Jump to

Keyboard shortcuts

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