Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create sync methods for password hashing #68

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"lodash": "4.17.21",
"node-fetch": "2.6.0",
"randombytes": "2.1.0",
"scrypt-js": "2.0.4",
"scrypt-js": "3.0.1",
"sha3": "2.0.4",
"smart-buffer": "4.2.0",
"tiny-secp256k1": "1.1.3"
Expand Down
16 changes: 0 additions & 16 deletions src/declarations/scrypt-js.d.ts

This file was deleted.

17 changes: 16 additions & 1 deletion src/getHKDFKeysFromPassword/getHKDFKeysFromPassword.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import getHKDFKeysFromPassword from './getHKDFKeysFromPassword'
import getHKDFKeysFromPassword, { syncGetHKDFKeysFromPassword } from './getHKDFKeysFromPassword'

import stringify from '../stringify'

Expand All @@ -16,8 +16,23 @@ testVectors.forEach((vector, idx) =>
})
)

testVectors.forEach((vector, idx) =>
test(`passes test vector ${idx + 1} (sync)`, () => {
const output = syncGetHKDFKeysFromPassword(vector.password, vector.salt)

expect(stringify(output.authKey)).toBe(vector.authKey)
expect(stringify(output.encryptionKey)).toBe(vector.encryptionKey)
})
)

test('generates symmetrical keys', async () => {
const output = await getHKDFKeysFromPassword(password, salt)

expect(output.authKey.length).toBe(output.encryptionKey.length)
})

test('generates symmetrical keys (sync)', () => {
const output = syncGetHKDFKeysFromPassword(password, salt)

expect(output.authKey.length).toBe(output.encryptionKey.length)
})
10 changes: 10 additions & 0 deletions src/getHKDFKeysFromPassword/getHKDFKeysFromPassword.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import hkdf from 'futoin-hkdf'
import hashPassword from '../hashPassword'
import HKDFKeys from '../types/HKDFKeys'
import { syncHashPassword } from '../hashPassword/hashPassword'

/*
HKDF parameters
Expand All @@ -26,3 +27,12 @@ export default async function getHKDFKeysFromPassword(password: string, salt: st
encryptionKey: hkdf(hashed, length, { hash, info: 'encryption', salt })
}
}

export function syncGetHKDFKeysFromPassword(password: string, salt: string): HKDFKeys {
const hashed = syncHashPassword(password, salt)

return {
authKey: hkdf(hashed, length, { hash, info: 'auth', salt }),
encryptionKey: hkdf(hashed, length, { hash, info: 'encryption', salt })
}
}
11 changes: 10 additions & 1 deletion src/hashPassword/hashPassword.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import hashPassword from './hashPassword'
import hashPassword, { syncHashPassword } from './hashPassword'

import stringify from '../stringify'

Expand All @@ -10,3 +10,12 @@ test('should properly hash a password', async () => {

expect(stringify(output)).toBe(expectation)
})

test('should properly hash a password (sync)', () => {
const password = 'hunter2'
const salt = 'b0cd9948365b'
const output = syncHashPassword(password, salt)
const expectation = 'bd38c1f44bfc5e6d0ac281c9b87cbd97e5a79134c960d856e4268fe2ca16f5e9'

expect(stringify(output)).toBe(expectation)
})
20 changes: 6 additions & 14 deletions src/hashPassword/hashPassword.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import scrypt from 'scrypt-js'
import { scrypt, syncScrypt } from 'scrypt-js'

import normalizeString from '../utils/normalizeString'

Expand All @@ -17,18 +17,10 @@ const dkLen = 32
* Hashes a plaintext password via the
* [scrypt key derivation function](https://en.wikipedia.org/wiki/Scrypt).
*/
export default function hashPassword(password: string, salt: string): Promise<Buffer> {
return new Promise(res =>
scrypt(normalizeString(password), normalizeString(salt), N, r, p, dkLen, (error: Error, _: number, key: string) => {
// throw instead of reject because this will only happen on code error
if (error) {
throw error
}
export default async function hashPassword(password: string, salt: string): Promise<Buffer> {
return Buffer.from(await scrypt(normalizeString(password), normalizeString(salt), N, r, p, dkLen))
}

// Progress tracker unhandled, we can incorporate it later if needed
if (key) {
return res(Buffer.from(key))
}
})
)
export function syncHashPassword(password: string, salt: string): Buffer {
return Buffer.from(syncScrypt(normalizeString(password), normalizeString(salt), N, r, p, dkLen))
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4597,10 +4597,10 @@ sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==

scrypt-js@2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16"
integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==
scrypt-js@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312"
integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==

secp256k1@^3.0.1:
version "3.7.1"
Expand Down