Skip to content

Commit

Permalink
Updated README and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
riverrun committed Feb 12, 2019
1 parent 198e85a commit 94114f0
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 120 deletions.
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Changelog

## v2.0.0

* Enhancements
* Updated to use the Comeonin and Comeonin.PasswordHash behaviours (Comeonin v5.0)

## v1.0.0

* Enhancements
* Updated C NIF code to use dirty schedulers

## v0.12.0

* Changes
* Created separate Bcrypt library
60 changes: 19 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
# Bcrypt

[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/alovedalongthe)
[![Hex.pm Version](http://img.shields.io/hexpm/v/bcrypt_elixir.svg)](https://hex.pm/packages/bcrypt_elixir)

Bcrypt password hashing algorithm for Elixir.
Bcrypt password hashing library for Elixir.

Bcrypt is a well-tested password-based key derivation function that
can be configured to remain slow and resistant to brute-force attacks
even as computational power increases.

This version is based on the OpenBSD version of Bcrypt and supports
the `$2b$` and `$2a$` prefixes. For advice on how to use hashes with
the `$2y$` prefix, see [this issue](https://github.com/riverrun/comeonin/issues/103).

This library can be used on its own, or it can be used together
with [Comeonin](https://hexdocs.pm/comeonin/api-reference.html),
which provides a higher-level api.

## Installation

1. Add bcrypt_elixir to the `deps` section of your mix.exs file:
Expand All @@ -26,12 +17,12 @@ If you are using Erlang >20:
```elixir
def deps do
[
{:bcrypt_elixir, "~> 1.1"}
{:bcrypt_elixir, "~> 2.0"}
]
end
```

If you are NOT using Erlang 19 or below:
If you are using Erlang 19 or below:

```elixir
def deps do
Expand All @@ -42,7 +33,7 @@ end
```

2. Make sure you have a C compiler installed.
See the [Comeonin wiki](https://github.com/riverrun/comeonin/wiki) for details.
See the [Comeonin wiki](https://github.com/riverrun/comeonin/wiki/Requirements) for details.

3. Optional: during tests (and tests only), you may want to reduce the number of rounds
so it does not slow down your test suite. If you have a config/test.exs, you should
Expand All @@ -52,34 +43,16 @@ add:
config :bcrypt_elixir, :log_rounds, 4
```

## Use

In most cases, you will just need to use the following three functions:

* hash_pwd_salt - hash a password with a randomly-generated salt
* verify_pass - check the password by comparing it with a stored hash
* no_user_verify - perform a dummy check to make user enumeration more difficult
## Comeonin wiki

See the documentation for the Bcrypt module for more information.
See the [Comeonin wiki](https://github.com/riverrun/comeonin/wiki) for more
information on the following topics:

For a lower-level api, see the documentation for Bcrypt.Base.

For further information about password hashing and using Bcrypt with Comeonin,
see the Comeonin [wiki](https://github.com/riverrun/comeonin/wiki).

### Docker

In order to use `bcrypt_elixir` in Docker, you will probably need to manually compile it in your Dockerfile. In order to do it on the Alpine image, you're going to need `make`, `gcc` and `libc-dev`. Add the following lines to your Dockerfile, right after `RUN mix deps.get`

```
RUN apk add --no-cache make gcc libc-dev
```

Remember to add your local `_build` and `deps` folders to `.dockerignore`, because otherwise, you'll see errors coming up.

### Deployment

See the Comeonin [deployment guide](https://github.com/riverrun/comeonin/wiki/Deployment).
* [algorithms](https://github.com/riverrun/comeonin/wiki/Choosing-the-password-hashing-algorithm)
* [requirements](https://github.com/riverrun/comeonin/wiki/Requirements)
* [deployment](https://github.com/riverrun/comeonin/wiki/Deployment)
* including information about using Docker
* [references](https://github.com/riverrun/comeonin/wiki/References)

## Contributing

Expand All @@ -92,8 +65,13 @@ There are many ways you can contribute to the development of this library, inclu

## Donations

If you would like to buy me a cup of coffee, you can
do so through [paypal](https://www.paypal.me/alovedalongthe)
This software is offered free of charge, but if you find it useful
and you would like to buy me a cup of coffee, you can do so through
[paypal](https://www.paypal.me/alovedalongthe).

### Documentation

http://hexdocs.pm/bcrypt_elixir

### License

Expand Down
98 changes: 47 additions & 51 deletions lib/bcrypt.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,50 @@ defmodule Bcrypt do
@moduledoc """
Bcrypt password hashing library main module.
This library can be used on its own, or it can be used together with
[Comeonin](https://hexdocs.pm/comeonin/api-reference.html), which
provides a higher-level api.
This module implements the Comeonin and Comeonin.PasswordHash behaviours,
providing the following functions:
* `add_hash/2` - takes a password as input and returns a map containing the password hash
* `check_pass/3` - takes a user struct and password as input and verifies the password
* `no_user_verify/1` - runs the hash function, but always returns false
* `hash_pwd_salt/2` - hashes the password with a randomly-generated salt
* `verify_pass/2` - verifies a password
For a lower-level API, see Bcrypt.Base.
## Configuration
The following parameter can be set in the config file:
* `log_rounds` - the computational cost as number of log rounds
* the default is 12 (2^12 rounds)
If you are hashing passwords in your tests, it can be useful to add
the following to the `config/test.exs` file:
config :bcrypt_elixir, log_rounds: 4
NB. do not use this value in production.
## Options
In addition to the options listed below, the `add_hash`, `no_user_verify`
and `hash_pwd_salt` functions all take a `log_rounds` option, which can be
used to override the value in the config.
### add_hash
* `hash_key` - the key used in the map for the password hash
* the default is `password_hash`
### check_pass
* `hash_key` - the key used in the user struct for the password hash
* if this is not set, `check_pass` will look for `password_hash`, and then `encrypted_password`
* `hide_user` - run `no_user_verify` to prevent user enumeration
* the default is true
* set this to false if you do not want to hide usernames
## Bcrypt
Bcrypt is a key derivation function for passwords designed by Niels Provos
Expand All @@ -31,8 +69,11 @@ defmodule Bcrypt do
The `$2y$` prefix is not supported. For advice on how to use hashes with the
`$2y$` prefix, see [this issue](https://github.com/riverrun/comeonin/issues/103).
Hash the password with a salt which is randomly generated.
"""

use Comeonin

alias Bcrypt.Base

@doc """
Expand All @@ -47,39 +88,10 @@ defmodule Bcrypt do
by older libraries.
"""
def gen_salt(log_rounds \\ 12, legacy \\ false) do
:crypto.strong_rand_bytes(16)
|> Base.gensalt_nif(log_rounds, (legacy and 97) || 98)
Base.gensalt_nif(:crypto.strong_rand_bytes(16), log_rounds, (legacy and 97) || 98)
end

@doc """
Hash the password with a salt which is randomly generated.
## Configurable parameters
The following parameters can be set in the config file:
* `log_rounds` - the computational cost as number of log rounds, by default
it is 12 (2^12).
If you are hashing passwords in your tests, it can be useful to add
the following to the `config/test.exs` file:
config :bcrypt_elixir,
log_rounds: 4
NB. do not use this value in production.
## Options
There is one option (this can be used if you want to override the
value in the config):
* `:log_rounds` - override the application's configured computational cost.
* `:legacy` - whether to generate a salt with the old `$2a$` prefix. This
should only be used to generate hashes that will be checked by older
libraries.
"""
@impl true
def hash_pwd_salt(password, opts \\ []) do
Base.hash_password(
password,
Expand All @@ -90,28 +102,12 @@ defmodule Bcrypt do
)
end

@doc """
Check the password.
The check is performed in constant time to avoid timing attacks.
"""
@impl true
def verify_pass(password, stored_hash) do
Base.checkpass_nif(:binary.bin_to_list(password), :binary.bin_to_list(stored_hash))
|> handle_verify
end

@doc """
A dummy verify function to help prevent user enumeration.
This always returns false. The reason for implementing this check is
in order to make it more difficult for an attacker to identify users
by timing responses.
"""
def no_user_verify(opts \\ []) do
hash_pwd_salt("password", opts)
false
end

defp handle_verify(0), do: true
defp handle_verify(_), do: false
end
5 changes: 4 additions & 1 deletion lib/bcrypt/stats.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ defmodule Bcrypt.Stats do
@moduledoc """
Module to provide statistics for the Bcrypt password hashing function.
## Configuring Bcrypt
The `report` function in this module can be used to help you configure
Bcrypt.
## Configuration
There is one configuration option for Bcrypt - log_rounds.
Increasing this value will increase the complexity, and time
Expand Down
5 changes: 3 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule BcryptElixir.Mixfile do
use Mix.Project

@version "1.1.1"
@version "2.0.0"

@description """
Bcrypt password hashing algorithm for Elixir
Expand All @@ -11,7 +11,7 @@ defmodule BcryptElixir.Mixfile do
[
app: :bcrypt_elixir,
version: @version,
elixir: "~> 1.4",
elixir: "~> 1.7",
start_permanent: Mix.env() == :prod,
compilers: [:elixir_make] ++ Mix.compilers(),
description: @description,
Expand All @@ -29,6 +29,7 @@ defmodule BcryptElixir.Mixfile do

defp deps do
[
{:comeonin, "~> 5.0"},
{:elixir_make, "~> 0.4", runtime: false},
{:ex_doc, "~> 0.19", only: :dev, runtime: false}
]
Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
%{
"comeonin": {:git, "https://github.com/riverrun/comeonin.git", "47cd3ce2bbbc540d1d84d1ae0ba4e73e2373b30d", [branch: "v5.0"]},
"earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [:mix], [], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.4.2", "332c649d08c18bc1ecc73b1befc68c647136de4f340b548844efc796405743bf", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
Expand Down
Loading

0 comments on commit 94114f0

Please sign in to comment.