Skip to content

Commit

Permalink
Merge pull request #29 from JamesBroadberry/issue/28
Browse files Browse the repository at this point in the history
Fix cipher being bypassed when running with Deno 1.23.0
  • Loading branch information
JamesBroadberry authored Jun 18, 2022
2 parents 6cb90de + 2acc8e8 commit fb6e55a
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 13 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
deno: ["v1.9.0", "v1.x"]
deno: ["v1.9.0", "v1.23.0", "v1.x"]
name: Test run with Deno ${{ matrix.deno }} on ${{ matrix.os }}
steps:
- uses: actions/checkout@master
Expand All @@ -25,4 +25,4 @@ jobs:
run: deno fmt --check --ignore=./README.md

- name: Run tests
run: deno test --unstable --allow-read
run: deno test --allow-read --allow-net
35 changes: 25 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,27 @@
[![release](https://img.shields.io/github/v/release/jamesbroadberry/deno-bcrypt.svg?color=green&label=latest)](https://github.com/JamesBroadberry/deno-bcrypt/releases)
[![ci](https://github.com/JamesBroadberry/deno-bcrypt/workflows/ci/badge.svg)](https://github.com/JamesBroadberry/deno-bcrypt/actions)

This is a port from [jBCrypt](https://github.com/jeremyh/jBCrypt) to TypeScript for use in [Deno](https://deno.land/).
This is a port from [jBCrypt](https://github.com/jeremyh/jBCrypt) to TypeScript
for use in [Deno](https://deno.land/).

It has zero third-party dependencies.

Running in sync requires no permissions.
Running in async functionality requires --allow-net
Running in sync requires no permissions. Running in async functionality requires
--allow-net

## Import

If you don't want to specify a specific version and are happy to work with breaking changes, you can import this module like so:
If you don't want to specify a specific version and are happy to work with
breaking changes, you can import this module like so:

```ts
import * as bcrypt from "https://deno.land/x/bcrypt/mod.ts";
```

To ensure that you've got a specific version, it's recommend to import this module specifying a [specific release](https://github.com/JamesBroadberry/deno-bcrypt/releases) like so:
To ensure that you've got a specific version, it's recommend to import this
module specifying a
[specific release](https://github.com/JamesBroadberry/deno-bcrypt/releases) like
so:

```ts
import * as bcrypt from "https://deno.land/x/bcrypt@v0.3.0/mod.ts";
Expand All @@ -29,7 +34,8 @@ import * as bcrypt from "https://deno.land/x/bcrypt@v0.3.0/mod.ts";

### Async

The Async implementation requires WebWorkers which require --allow-net to import Deno standard modules from inside the Worker.
The Async implementation requires WebWorkers which require --allow-net to import
Deno standard modules from inside the Worker.

```ts
const hash = await bcrypt.hash("test");
Expand All @@ -50,7 +56,10 @@ const hash = await bcrypt.hash("test", salt);

### Sync/Blocking

It is not recommended to use this unless you're running a quick script since the BCrypt algorithm is computationally quite expensive. For example, if you're running a server and make multiple calls to it, other requests will be blocked. Using the Async methods are recommended.
It is not recommended to use this unless you're running a quick script since the
BCrypt algorithm is computationally quite expensive. For example, if you're
running a server and make multiple calls to it, other requests will be blocked.
Using the Async methods are recommended.

To hash a password (with auto-generated salt):

Expand All @@ -73,9 +82,15 @@ const hash = bcrypt.hashSync("test", salt);

### Older versions of Deno and/or BCrypt

Older versions of Deno will require an older version of this library (specifically < 0.3.0) because of the introduction of `TextEncoder`.
However, older version of this library require the `--unstable` flag when running.
Older versions of Deno will require an older version of this library
(specifically < 0.3.0) because of the introduction of `TextEncoder`. However,
older version of this library require the `--unstable` flag when running.

## Warnings

BCrypt v0.3.0 and below should NOT be used with Deno 1.23.0 or later since there's been a [breaking change in how Deno interprets the code](https://github.com/denoland/deno/issues/14900) and completely bypasses the cipher. Ensure that if you're running Deno 1.23.0 or later that you're using the latest version of BCrypt.

## Issues

For any bug reports or feature requests, please create an issue on [GitHub](https://github.com/JamesBroadberry/deno-bcrypt/issues).
For any bug reports or feature requests, please create an issue on
[GitHub](https://github.com/JamesBroadberry/deno-bcrypt/issues).
2 changes: 1 addition & 1 deletion src/bcrypt/bcrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1193,7 +1193,7 @@ function crypt_raw(
}

for (i = 0; i < 64; i++) {
for (j = 0; j < clen >> 1; j++) encipher(cdata, j << 1);
for (j = 0; j < (clen >> 1); j++) encipher(cdata, j << 1);
}

ret = new Uint8Array(clen * 4);
Expand Down
58 changes: 58 additions & 0 deletions test/mod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,61 @@ Deno.test({
assertEquals(passwordVerified, false);
},
});

Deno.test({
name: "hashing password then verifying using an external service works",
async fn(): Promise<void> {
const passwordToTest = "ThisIsAPassword1234";
const hashedPassword = bcrypt.hashSync(passwordToTest);

const res = await fetch("https://bcrypt.online/verify", {
"headers": {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
},
"body": `plain_text=${passwordToTest}&hash=${hashedPassword}`,
"method": "POST",
});

const data = await res.json();

assertEquals(data.is_verified, true);
},
});

Deno.test({
name:
"hashing password using an external service works then verifying locally works",
async fn(): Promise<void> {
const passwordToTest = "ThisIsAPassword1234";

const res = await fetch("https://bcrypt.online/calculate", {
"headers": {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
},
"body": `plain_text=${passwordToTest}&cost_factor=10`,
"method": "POST",
});

const data = await res.json();
const hashedPassword = data.hash;

const passwordVerified = await bcrypt.compare(
passwordToTest,
hashedPassword,
);

assertEquals(passwordVerified, true);
},
});

Deno.test({
name:
"comparing wrong plaintext with hash from another plaintext returns false",
async fn(): Promise<void> {
const hash = await bcrypt.hash("replicate");
const result = await bcrypt.compare("replicate", hash);
assertEquals(result, true);
const resultKo = await bcrypt.compare("wrongpassword", hash);
assertEquals(resultKo, false);
},
});

0 comments on commit fb6e55a

Please sign in to comment.