Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
recrsn committed Jun 1, 2020
2 parents e623bea + 96c41e2 commit 55dab19
Show file tree
Hide file tree
Showing 15 changed files with 2,033 additions and 3,483 deletions.
2 changes: 1 addition & 1 deletion .gitignore
@@ -1,5 +1,5 @@
.lock*
build
build*
*.node
*.sw[a-z]
node_modules
63 changes: 44 additions & 19 deletions .travis.yml
@@ -1,36 +1,61 @@
language: node_js

services:
- docker

env:
- LINUX_CXX=g++-4.8
- LINUX_CXX=g++-4.8

os:
- linux
- osx
- linux
- osx

arch:
- amd64
- arm64

node_js:
- "6"
- "7"
- "8"
- "9"
- "10"
- '10'
- '11'
- '12'
- '13'
- '14'

addons:
apt:
sources:
- ubuntu-toolchain-r-test
- ubuntu-toolchain-r-test
packages:
- g++-4.8
- bc
- g++-4.8
- bc

before_install:
- echo Building for Node $TRAVIS_NODE_VERSION
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=$LINUX_CXX; $CXX --version; fi;
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then c++ --version; fi;
- npm install -g npm@latest
- echo Building for Node $TRAVIS_NODE_VERSION
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=$LINUX_CXX; $CXX --version;
fi;
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then c++ --version; fi;
- npm install -g npm@latest

install: true

script: npm test

after_success:
- if [[ $TRAVIS_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then echo "Publishing"; npm install node-pre-gyp-github@1.3.1; ./node_modules/.bin/node-pre-gyp configure; ./node_modules/.bin/node-pre-gyp build; ./node_modules/.bin/node-pre-gyp package; ./node_modules/.bin/node-pre-gyp-github publish --release; fi;
script:
- npm test
- "./node_modules/.bin/node-pre-gyp configure"
- "./node_modules/.bin/node-pre-gyp build"
- "./node_modules/.bin/node-pre-gyp package"
- |
if [[ "$TRAVIS_OS_NAME" == "linux" ]]
then
docker run -w /src --entrypoint /bin/sh -v`pwd`:/src "node:${TRAVIS_NODE_VERSION}-alpine" test_alpine.sh
fi
deploy:
provider: releases
api_key:
secure: j4gQ+m02izaw56EOd0gEStHAjCRfSCkohDWvpABiPzh1YPM9MvfEMSIvzzjV/0oMqi3Sy7eGyFv47EgQHZvouW0I8BIUzxuTCE5wP8z2SjABXCa/rz4WTppTc9d9ABq8JSdz80JxEwjmuwnYeMwWgOd7sT/VDiMxLYaXj0JWO7w=
file_glob: true
file: build/stage/*/*
on:
node_js: '10'
repo: kelektiv/node.bcrypt.js
condition: $TRAVIS_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-\w)?
65 changes: 65 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,59 @@
# UNRELEASED

* Fix the bcrypt "wrap-around" bug. It affects passwords with lengths >= 255.
It is uncommon but it's a bug nevertheless. Previous attempts to fix the bug
was unsuccessful.
* Experimental support for z/OS

# 4.0.1 (2020-02-27)

* Fix compilation errors in Alpine linux

# 4.0.0 (2020-02-17)

* Switch to NAPI bcrypt
* Drop support for NodeJS 8

# 3.0.8 (2019-12-31)

* Update `node-pre-gyp` to 0.14
* Pre-built binaries for NodeJS 13

# 3.0.7 (2019-10-18)

* Update `nan` to 2.14.0
* Update `node-pre-gyp` to 0.13

# 3.0.6 (2019-04-11)

* Update `nan` to 2.13.2

# 3.0.5 (2019-03-19)

* Update `nan` to 2.13.1
* NodeJS 12 compatibility
* Remove `node-pre-gyp` from bundled dependencies

# 3.0.4-napi (2019-03-08)

* Sync N-API bcrypt with NAN bcrypt

# 3.0.4 (2019-02-07)

* Fix GCC, NAN and V8 deprecation warnings

# 3.0.3 (2018-12-19)

* Update `nan` to 2.12.1

# 3.0.2 (2018-10-18)

* Update `nan` to 2.11.1

# 3.0.1 (2018-09-20)

* Update `nan` to 2.11.0

# 3.0.0 (2018-07-06)

* Drop support for NodeJS <= 4
Expand All @@ -10,6 +66,15 @@

* Make `2b` the default bcrypt version

# 1.1.0-napi (2018-01-21)

* Initial support for [N-API](https://nodejs.org/api/n-api.html)

# 1.0.3 (2016-08-23)

* update to nan v2.6.2 for NodeJS 8 support
* Fix: use npm scripts instead of node-gyp directly.

# 1.0.2 (2016-12-31)

* Fix `compare` promise rejection with invalid arguments
Expand Down
95 changes: 54 additions & 41 deletions README.md
Expand Up @@ -2,48 +2,49 @@
[![Build Status](https://travis-ci.org/kelektiv/node.bcrypt.js.svg?branch=master)](https://travis-ci.org/kelektiv/node.bcrypt.js)
[![Dependency Status](https://david-dm.org/kelektiv/node.bcrypt.js.svg)](https://david-dm.org/kelektiv/node.bcrypt.js)

Lib to help you hash passwords.
[bcrypt on wikipedia][bcryptwiki]
A library to help you hash passwords.

Catalyst for this module: [How To Safely Store A Password][codahale]
You can read about [bcrypt in Wikipedia][bcryptwiki] as well as in the following article:
[How To Safely Store A Password][codahale]

## If You Are Submitting Bugs/Issues
## If You Are Submitting Bugs or Issues

First, make sure that the version of node you are using is a _stable_ version. You'll know this because it'll have an even major release number. We do not currently support unstable versions and while the module may happen to work on some unstable versions you'll find that we quickly close issues if you're not using a stable version.
Verify that the node version you are using is a _stable_ version; it has an even major release number. Unstable versions are currently not supported and issues created while using an unstable version will be closed.

If you are on a stable version of node, we can't magically know what you are doing to expose an issue, it is best if you provide a snippet of code or log files if you're having an install issue. This snippet need not include your secret sauce, but it must replicate the issue you are describing. The issues that get closed without resolution tend to be the ones that don't help us help you. Thanks.
If you are on a stable version of node, please provide a sufficient code snippet or log files for installation issues. The code snippet does not require you to include confidential information. However, it must provide enough information such that the problem can be replicable. Issues which are closed without resolution often lack required information for replication.


## Version Compatibility

| Node Version | Bcrypt Version |
| -------------- | -------------- |
| 0.4 | <= 0.4 |
| 0.6, 0.8, 0.10 | >= 0.5 |
| 0.11 | >= 0.8 |
| 4 | < 2.1 |
| 8 | >= 1.0.3 |
| 10 | >= 3 |
| Node Version | Bcrypt Version |
| -------------- | ------------------|
| 0.4 | <= 0.4 |
| 0.6, 0.8, 0.10 | >= 0.5 |
| 0.11 | >= 0.8 |
| 4 | <= 2.1.0 |
| 8 | >= 1.0.3 < 4.0.0 |
| 10, 11 | >= 3 |
| 12 | >= 3.0.6 |

`node-gyp` only works with stable/released versions of node. Since the `bcrypt` module uses `node-gyp` to build and install you'll need a stable version of node to use bcrypt. If you do not you'll likely see an error that starts with:
`node-gyp` only works with stable/released versions of node. Since the `bcrypt` module uses `node-gyp` to build and install, you'll need a stable version of node to use bcrypt. If you do not, you'll likely see an error that starts with:

```
gyp ERR! stack Error: "pre" versions of node cannot be installed, use the --nodedir flag instead
```

## Security Issues/Concerns
## Security Issues And Concerns

> Per bcrypt implementation, only the first 72 characters of a string are used. Any extra characters are ignored when matching passwords.
> Per bcrypt implementation, only the first 72 bytes of a string are used. Any extra bytes are ignored when matching passwords. Note that this is not the first 72 *characters*. It is possible for a string to contain less than 72 characters, while taking up more than 72 bytes (e.g. a UTF-8 encoded string containing emojis).
As should be the case with any security tool, this library should be scrutinized by anyone using it. If you find or suspect an issue with the code- please bring it to my attention and I'll spend some time trying to make sure that this tool is as secure as possible.
As should be the case with any security tool, this library should be scrutinized by anyone using it. If you find or suspect an issue with the code, please bring it to my attention and I'll spend some time trying to make sure that this tool is as secure as possible.

To make it easier for people using this tool to analyze what has been surveyed, here is a list of BCrypt related security issues/concerns as they've come up.

* An [issue with passwords][jtr] was found with a version of the Blowfish algorithm developed for John the Ripper. This is not present in the OpenBSD version and is thus not a problem for this module. HT [zooko][zooko].

## Compatibility Note

This library supports `$2a$` and `$2b$` prefix bcrypt hashes. `$2x$` and `$2y$` hashes are specific to bcrypt implementation developed for Jon the Ripper. In theory, they should be compatible with `$2b$` prefix.
This library supports `$2a$` and `$2b$` prefix bcrypt hashes. `$2x$` and `$2y$` hashes are specific to bcrypt implementation developed for John the Ripper. In theory, they should be compatible with `$2b$` prefix.

Compatibility with hashes generated by other languages is not 100% guaranteed due to difference in character encodings. However, it should not be an issue for most cases.

Expand Down Expand Up @@ -71,7 +72,7 @@ npm install bcrypt

_Pre-built binaries for various NodeJS versions are made available on a best-effort basis._

Only the current stable and the supported LTS releases are actively tested against. Please note that there may be an interval between the release of the module and the availabilty of the compiled modules.
Only the current stable and supported LTS releases are actively tested against. Please note that there may be an interval between the release of the module and the availabilty of the compiled modules.

Currently, we have pre-built binaries that support the following platforms:

Expand All @@ -85,14 +86,14 @@ If you face an error like this:
node-pre-gyp ERR! Tried to download(404): https://github.com/kelektiv/node.bcrypt.js/releases/download/v1.0.2/bcrypt_lib-v1.0.2-node-v48-linux-x64.tar.gz
```

Make sure you have the appropriate dependencies installed and configured for your platform. You can find installation instructions for the dependencies for some common platforms [in this page][depsinstall].
make sure you have the appropriate dependencies installed and configured for your platform. You can find installation instructions for the dependencies for some common platforms [in this page][depsinstall].

## Usage

### async (recommended)

```javascript
var bcrypt = require('bcrypt');
const bcrypt = require('bcrypt');
const saltRounds = 10;
const myPlaintextPassword = 's0/\/\P4$$w0rD';
const someOtherPlaintextPassword = 'not_bacon';
Expand All @@ -114,7 +115,7 @@ Technique 2 (auto-gen a salt and hash):

```javascript
bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
// Store hash in your password DB.
// Store hash in your password DB.
});
```

Expand All @@ -124,17 +125,15 @@ Note that both techniques achieve the same end-result.

```javascript
// Load hash from your password DB.
bcrypt.compare(myPlaintextPassword, hash, function(err, res) {
// res == true
bcrypt.compare(myPlaintextPassword, hash, function(err, result) {
// result == true
});
bcrypt.compare(someOtherPlaintextPassword, hash, function(err, res) {
// res == false
bcrypt.compare(someOtherPlaintextPassword, hash, function(err, result) {
// result == false
});
```

The "compare" function counters timing attacks (using a so-called 'constant-time' algorithm).
In general, don't use the normal JavaScript string comparison functions to compare passwords,
cryptographic keys, or cryptographic hashes if they are relevant to security.
[A Note on Timing Attacks](#a-note-on-timing-attacks)

### with promises

Expand All @@ -149,11 +148,11 @@ bcrypt.hash(myPlaintextPassword, saltRounds).then(function(hash) {
```
```javascript
// Load hash from your password DB.
bcrypt.compare(myPlaintextPassword, hash).then(function(res) {
// res == true
bcrypt.compare(myPlaintextPassword, hash).then(function(result) {
// result == true
});
bcrypt.compare(someOtherPlaintextPassword, hash).then(function(res) {
// res == false
bcrypt.compare(someOtherPlaintextPassword, hash).then(function(result) {
// result == false
});
```

Expand All @@ -176,7 +175,7 @@ async function checkUser(username, password) {
### sync

```javascript
var bcrypt = require('bcrypt');
const bcrypt = require('bcrypt');
const saltRounds = 10;
const myPlaintextPassword = 's0/\/\P4$$w0rD';
const someOtherPlaintextPassword = 'not_bacon';
Expand All @@ -187,15 +186,15 @@ const someOtherPlaintextPassword = 'not_bacon';
Technique 1 (generate a salt and hash on separate function calls):

```javascript
var salt = bcrypt.genSaltSync(saltRounds);
var hash = bcrypt.hashSync(myPlaintextPassword, salt);
const salt = bcrypt.genSaltSync(saltRounds);
const hash = bcrypt.hashSync(myPlaintextPassword, salt);
// Store hash in your password DB.
```

Technique 2 (auto-gen a salt and hash):

```javascript
var hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
const hash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
// Store hash in your password DB.
```

Expand All @@ -208,9 +207,8 @@ As with async, both techniques achieve the same end-result.
bcrypt.compareSync(myPlaintextPassword, hash); // true
bcrypt.compareSync(someOtherPlaintextPassword, hash); // false
```
The "compareSync" function counters timing attacks (using a so-called 'constant-time' algorithm).
In general, don't use the normal JavaScript string comparison functions to compare passwords,
cryptographic keys, or cryptographic hashes if they are relevant to security.

[A Note on Timing Attacks](#a-note-on-timing-attacks)

### Why is async mode recommended over sync mode?
If you are using bcrypt on a simple script, using the sync mode is perfectly fine. However, if you are using bcrypt on a server, the async mode is recommended. This is because the hashing done by bcrypt is CPU intensive, so the sync version will block the event loop and prevent your application from servicing any other inbound requests or events. The async version uses a thread pool which does not block the main event loop.
Expand Down Expand Up @@ -267,6 +265,18 @@ From @garthk, on a 2GHz core you can roughly expect:
rounds=31: 2-3 days/hash


## A Note on Timing Attacks

Because it's come up multiple times in this project, and other bcrypt projects, it needs to be said. The bcrypt comparison function is not susceptible to timing attacks. From codahale/bcrypt-ruby#42:

> One of the desired properties of a cryptographic hash function is preimage attack resistance, which means there is no shortcut for generating a message which, when hashed, produces a specific digest.
A great thread on this, in much more detail can be found @ codahale/bcrypt-ruby#43

If you're unfamiliar with timing attacks and want to learn more you can find a great writeup @ [A Lesson In Timing Attacks][timingatk]

However, timing attacks are real. And, the comparison function is _not_ time safe. What that means is that it may exit the function early in the comparison process. This happens because of the above. We don't need to be careful that an attacker is going to learn anything, and our comparison function serves to provide a comparison of hashes, it is a utility to the overall purpose of the library. If you end up using it for something else we cannot guarantee the security of the comparator. Keep that in mind as you use the library.

## Hash Info

The characters that comprise the resultant hash are `./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$`.
Expand Down Expand Up @@ -308,6 +318,7 @@ The code for this comes from a few sources:
* [Sean McArthur][seanmonstar] - Windows Support
* [Fanie Oosthuysen][weareu] - Windows Support
* [Amitosh Swain Mahapatra][agathver] - $2b$ hash support, ES6 Promise support
* [Nicola Del Gobbo][NickNaso] - Initial implementation with N-API

## License
Unless stated elsewhere, file headers or otherwise, the license as stated in the LICENSE file.
Expand All @@ -318,6 +329,7 @@ Unless stated elsewhere, file headers or otherwise, the license as stated in the
[gh13]: https://github.com/ncb000gt/node.bcrypt.js/issues/13
[jtr]: http://www.openwall.com/lists/oss-security/2011/06/20/2
[depsinstall]: https://github.com/kelektiv/node.bcrypt.js/wiki/Installation-Instructions
[timingatk]: https://codahale.com/a-lesson-in-timing-attacks/

[shadowfiend]:https://github.com/Shadowfiend
[thegoleffect]:https://github.com/thegoleffect
Expand All @@ -335,3 +347,4 @@ Unless stated elsewhere, file headers or otherwise, the license as stated in the
[seanmonstar]:https://github.com/seanmonstar
[weareu]:https://github.com/weareu
[agathver]:https://github.com/Agathver
[NickNaso]: https://github.com/NickNaso

0 comments on commit 55dab19

Please sign in to comment.