Skip to content

Commit 52c4553

Browse files
authored
fix!(argon2): respect the salt provided in hash options (#899)
1 parent fea946f commit 52c4553

File tree

13 files changed

+98
-73
lines changed

13 files changed

+98
-73
lines changed

depracted/deno-lint/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"typanion": "^3.14.0"
7474
},
7575
"devDependencies": {
76-
"@napi-rs/cli": "^3.0.0-alpha.54",
76+
"@napi-rs/cli": "^3.0.0-alpha.63",
7777
"@types/webpack": "^5.28.5"
7878
},
7979
"funding": {

packages/argon2/README.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,6 @@ It has a simple design aimed at the highest memory filling rate and effective us
2727
Hybrid that mixes Argon2i and Argon2d passes.
2828
Uses the Argon2i approach for the first half pass over memory and Argon2d approach for subsequent passes. This effectively places it in the “middle” between the other two: it doesn’t provide as good TMTO/GPU cracking resistance as Argon2d, nor as good of side-channel resistance as Argon2i, but overall provides the most well-rounded approach to both classes of attacks.
2929

30-
## Support matrix
31-
32-
| | node12 | node14 | node16 | node18 |
33-
| ------------------- | ------ | ------ | ------ | ------ |
34-
| Windows x64 |||||
35-
| Windows x32 |||||
36-
| Windows arm64 |||||
37-
| macOS x64 |||||
38-
| macOS arm64(m chip) |||||
39-
| Linux x64 gnu |||||
40-
| Linux x64 musl |||||
41-
| Linux arm gnu |||||
42-
| Linux arm64 gnu |||||
43-
| Linux arm64 musl |||||
44-
| Android arm64 |||||
45-
| Android armv7 |||||
46-
| FreeBSD x64 |||||
47-
4830
# Benchmarks
4931

5032
See [benchmark/](benchmark/argon2.js).

packages/argon2/__test__/argon2.spec.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { randomBytes } from 'crypto'
1+
import { randomBytes } from 'node:crypto'
22

33
import test from 'ava'
44

@@ -43,6 +43,30 @@ test('should be able to hash string', async (t) => {
4343
)
4444
})
4545

46+
test('should be able to hash string with a defined salt', async (t) => {
47+
await t.notThrowsAsync(() =>
48+
hash('whatever', {
49+
salt: randomBytes(32),
50+
}),
51+
)
52+
await t.notThrowsAsync(() =>
53+
hash('whatever', {
54+
secret: randomBytes(32),
55+
salt: randomBytes(32),
56+
}),
57+
)
58+
59+
const salt = randomBytes(32)
60+
t.is(
61+
await hash('whatever', {
62+
salt,
63+
}),
64+
await hash('whatever', {
65+
salt,
66+
}),
67+
)
68+
})
69+
4670
test('should be able to hashRaw string with a defined salt', async (t) => {
4771
await t.notThrowsAsync(() => hash('whatever'))
4872
await t.notThrowsAsync(() =>

packages/argon2/benchmark/argon2.js

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,38 @@
1-
const { cpus } = require('os')
1+
import { cpus } from 'node:os'
22

3-
const nodeArgon2 = require('argon2')
4-
const { Suite } = require('benchmark')
5-
const chalk = require('chalk')
3+
import nodeArgon2 from 'argon2'
4+
import { Bench } from 'tinybench'
65

7-
const { hash, verify, Algorithm } = require('../index')
6+
import { hash, verify, Algorithm } from '../index.js'
87

98
const PASSWORD = '$v=19$m=4096,t=3,p=1$fyLYvmzgpBjDTP6QSypj3g$pb1Q3Urv1amxuFft0rGwKfEuZPhURRDV7TJqcBnwlGo'
109
const CORES = cpus().length
1110

12-
const suite = new Suite('Hash with all cores')
13-
14-
suite
15-
.add(
16-
'@node-rs/argon',
17-
async (deferred) => {
18-
await hash(PASSWORD, {
19-
algorithm: Algorithm.Argon2id,
20-
parallelism: CORES,
21-
})
22-
deferred.resolve()
23-
},
24-
{ defer: true },
25-
)
26-
.add(
27-
'node-argon',
28-
async (deferred) => {
29-
await nodeArgon2.hash(PASSWORD, { type: nodeArgon2.argon2id, parallelism: CORES })
30-
deferred.resolve()
31-
},
32-
{
33-
defer: true,
34-
},
35-
)
36-
.on('cycle', function (event) {
37-
console.info(String(event.target))
11+
const HASHED = await hash(PASSWORD, {
12+
algorithm: Algorithm.Argon2id,
13+
parallelism: CORES,
14+
})
15+
16+
const bench = new Bench('Hash with all cores')
17+
18+
bench
19+
.add('@node-rs/argon hash', async () => {
20+
await hash(PASSWORD, {
21+
algorithm: Algorithm.Argon2id,
22+
parallelism: CORES,
23+
})
24+
})
25+
.add('node-argon hash', async () => {
26+
await nodeArgon2.hash(PASSWORD, { type: nodeArgon2.argon2id, parallelism: CORES })
3827
})
39-
.on('complete', function () {
40-
console.info(`${this.name} bench suite: Fastest is ${chalk.green(this.filter('fastest').map('name'))}`)
28+
.add('@node-rs/argon verify', async () => {
29+
console.assert(await verify(HASHED, PASSWORD))
4130
})
42-
.run()
31+
.add('node-argon verify', async () => {
32+
console.assert(await nodeArgon2.verify(HASHED, PASSWORD))
33+
})
34+
35+
await bench.warmup()
36+
await bench.run()
37+
38+
console.table(bench.table())
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"type": "module"
3+
}

packages/argon2/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@
6262
"version": "napi version && git add npm"
6363
},
6464
"devDependencies": {
65-
"@napi-rs/cli": "^3.0.0-alpha.54",
65+
"@napi-rs/cli": "^3.0.0-alpha.63",
6666
"argon2": "^0.41.0",
67-
"cross-env": "^7.0.3"
67+
"cross-env": "^7.0.3",
68+
"tinybench": "^2.9.0"
6869
}
6970
}

packages/argon2/src/lib.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,18 @@ impl Task for HashTask {
125125
type JsValue = String;
126126

127127
fn compute(&mut self) -> Result<Self::Output> {
128-
let salt = SaltString::generate(&mut OsRng);
128+
let salt = if let Some(salt) = &self.options.salt {
129+
SaltString::encode_b64(salt)
130+
.map_err(|err| Error::new(Status::InvalidArg, format!("{err}")))?
131+
} else {
132+
SaltString::generate(&mut OsRng)
133+
};
134+
let hasher = self
135+
.options
136+
.to_argon()
137+
.map_err(|err| Error::new(Status::InvalidArg, format!("{err}")))?;
129138

130-
let hasher = self.options.to_argon();
131139
hasher
132-
.map_err(|err| Error::new(Status::InvalidArg, format!("{err}")))?
133140
.hash_password(self.password.as_slice(), &salt)
134141
.map_err(|err| Error::new(Status::GenericFailure, format!("{err}")))
135142
.map(|h| h.to_string())
@@ -263,8 +270,12 @@ impl Task for VerifyTask {
263270
type JsValue = bool;
264271

265272
fn compute(&mut self) -> Result<Self::Output> {
266-
let parsed_hash = argon2::PasswordHash::new(self.hashed.as_str())
267-
.map_err(|err| Error::new(Status::InvalidArg, format!("{err}")))?;
273+
let parsed_hash = argon2::PasswordHash::new(self.hashed.as_str()).map_err(|err| {
274+
Error::new(
275+
Status::InvalidArg,
276+
format!("Invalid hashed password: {err}"),
277+
)
278+
})?;
268279
let argon2 = self.options.to_argon();
269280
Ok(
270281
argon2

packages/bcrypt/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"url": "https://github.com/napi-rs/node-rs/issues"
7171
},
7272
"devDependencies": {
73-
"@napi-rs/cli": "^3.0.0-alpha.54",
73+
"@napi-rs/cli": "^3.0.0-alpha.63",
7474
"@types/bcrypt": "^5.0.2",
7575
"bcrypt": "^5.1.1",
7676
"bcryptjs": "^2.4.3",

packages/crc32/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"url": "https://github.com/napi-rs/node-rs/issues"
6565
},
6666
"devDependencies": {
67-
"@napi-rs/cli": "^3.0.0-alpha.54",
67+
"@napi-rs/cli": "^3.0.0-alpha.63",
6868
"@types/crc": "^3.8.3",
6969
"buffer": "^6.0.3",
7070
"crc": "^4.3.2",

packages/jieba/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"url": "https://github.com/napi-rs/node-rs/issues"
6565
},
6666
"devDependencies": {
67-
"@napi-rs/cli": "^3.0.0-alpha.54",
67+
"@napi-rs/cli": "^3.0.0-alpha.63",
6868
"nodejieba": "^3.0.0"
6969
},
7070
"funding": {

packages/jsonwebtoken/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"node": ">= 10"
6565
},
6666
"devDependencies": {
67-
"@napi-rs/cli": "^3.0.0-alpha.54",
67+
"@napi-rs/cli": "^3.0.0-alpha.63",
6868
"@types/jsonwebtoken": "^9.0.6",
6969
"jsonwebtoken": "^9.0.2"
7070
}

packages/xxhash/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"url": "https://github.com/napi-rs/node-rs/issues"
6767
},
6868
"devDependencies": {
69-
"@napi-rs/cli": "^3.0.0-alpha.54",
69+
"@napi-rs/cli": "^3.0.0-alpha.63",
7070
"@types/xxhashjs": "^0.2.4",
7171
"webpack": "^5.92.1",
7272
"xxhash": "^0.3.0",

yarn.lock

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ __metadata:
434434
languageName: node
435435
linkType: hard
436436

437-
"@napi-rs/cli@npm:^3.0.0-alpha.54, @napi-rs/cli@npm:^3.0.0-alpha.63":
437+
"@napi-rs/cli@npm:^3.0.0-alpha.63":
438438
version: 3.0.0-alpha.63
439439
resolution: "@napi-rs/cli@npm:3.0.0-alpha.63"
440440
dependencies:
@@ -1024,17 +1024,18 @@ __metadata:
10241024
version: 0.0.0-use.local
10251025
resolution: "@node-rs/argon2@workspace:packages/argon2"
10261026
dependencies:
1027-
"@napi-rs/cli": "npm:^3.0.0-alpha.54"
1027+
"@napi-rs/cli": "npm:^3.0.0-alpha.63"
10281028
argon2: "npm:^0.41.0"
10291029
cross-env: "npm:^7.0.3"
1030+
tinybench: "npm:^2.9.0"
10301031
languageName: unknown
10311032
linkType: soft
10321033

10331034
"@node-rs/bcrypt@workspace:packages/bcrypt":
10341035
version: 0.0.0-use.local
10351036
resolution: "@node-rs/bcrypt@workspace:packages/bcrypt"
10361037
dependencies:
1037-
"@napi-rs/cli": "npm:^3.0.0-alpha.54"
1038+
"@napi-rs/cli": "npm:^3.0.0-alpha.63"
10381039
"@types/bcrypt": "npm:^5.0.2"
10391040
bcrypt: "npm:^5.1.1"
10401041
bcryptjs: "npm:^2.4.3"
@@ -1046,7 +1047,7 @@ __metadata:
10461047
version: 0.0.0-use.local
10471048
resolution: "@node-rs/crc32@workspace:packages/crc32"
10481049
dependencies:
1049-
"@napi-rs/cli": "npm:^3.0.0-alpha.54"
1050+
"@napi-rs/cli": "npm:^3.0.0-alpha.63"
10501051
"@types/crc": "npm:^3.8.3"
10511052
buffer: "npm:^6.0.3"
10521053
crc: "npm:^4.3.2"
@@ -1066,7 +1067,7 @@ __metadata:
10661067
version: 0.0.0-use.local
10671068
resolution: "@node-rs/jieba@workspace:packages/jieba"
10681069
dependencies:
1069-
"@napi-rs/cli": "npm:^3.0.0-alpha.54"
1070+
"@napi-rs/cli": "npm:^3.0.0-alpha.63"
10701071
nodejieba: "npm:^3.0.0"
10711072
languageName: unknown
10721073
linkType: soft
@@ -1075,7 +1076,7 @@ __metadata:
10751076
version: 0.0.0-use.local
10761077
resolution: "@node-rs/jsonwebtoken@workspace:packages/jsonwebtoken"
10771078
dependencies:
1078-
"@napi-rs/cli": "npm:^3.0.0-alpha.54"
1079+
"@napi-rs/cli": "npm:^3.0.0-alpha.63"
10791080
"@types/jsonwebtoken": "npm:^9.0.6"
10801081
jsonwebtoken: "npm:^9.0.2"
10811082
languageName: unknown
@@ -1085,7 +1086,7 @@ __metadata:
10851086
version: 0.0.0-use.local
10861087
resolution: "@node-rs/xxhash@workspace:packages/xxhash"
10871088
dependencies:
1088-
"@napi-rs/cli": "npm:^3.0.0-alpha.54"
1089+
"@napi-rs/cli": "npm:^3.0.0-alpha.63"
10891090
"@types/xxhashjs": "npm:^0.2.4"
10901091
webpack: "npm:^5.92.1"
10911092
xxhash: "npm:^0.3.0"
@@ -8246,6 +8247,13 @@ __metadata:
82468247
languageName: node
82478248
linkType: hard
82488249

8250+
"tinybench@npm:^2.9.0":
8251+
version: 2.9.0
8252+
resolution: "tinybench@npm:2.9.0"
8253+
checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c
8254+
languageName: node
8255+
linkType: hard
8256+
82498257
"tmp@npm:^0.0.33":
82508258
version: 0.0.33
82518259
resolution: "tmp@npm:0.0.33"

0 commit comments

Comments
 (0)