|forest 7167078570 Remove SHA256 impl and export a factory that takes SHA256 argument||6 months ago|
|test||7 months ago|
|thirdparty||4 years ago|
|.gitignore||1 year ago|
|.npmignore||1 year ago|
|LICENSE.txt||4 years ago|
|README.md||7 months ago|
|index.html||1 year ago|
|package-lock.json||7 months ago|
|package.json||7 months ago|
|scrypt.js||6 months ago|
The scrypt password-base key derivation function (pbkdf) is an algorithm designed to be brute-force resistant that converts human readable passwords into fixed length arrays of bytes, which can then be used as a key for symmetric block ciphers, private keys, et cetera.
The scrypt algorithm is, by design, expensive to execute, which increases the amount of time an attacker requires in order to brute force guess a password, adjustable by several parameters which can be tuned:
You should likely not use this module for node.js as there are many faster alternatives, but if you so wish to do so:
npm install scrypt-js
scrypt . scrypt ( password , salt , N , r , p , dkLen [ , progressCallback ] ) => Promise
Compute the scrypt PBKDF asynchronously using a Promise. If progressCallback is provided, it is periodically called with a single parameter, a number between 0 and 1 (inclusive) indicating the completion progress; it will always emit 0 at the beginning and 1 at the end, and numbers between may repeat.
scrypt . syncScrypt ( password , salt , N , r , p , dkLen ) => Uint8Array
Compute the scrypt PBKDF synchronously. Keep in mind this may stall UI and other tasks and the asynchronous version is highly preferred.
TL;DR - either only allow ASCII characters in passwords, or use String.prototype.normalize('NFKC') on any password
It is HIGHLY recommended that you do NOT pass strings into this (or any password-base key derivation function) library without careful consideration; you should convert your strings to a canonical format that you will use consistently across all platforms.
When encoding passwords with UTF-8, it is important to realize that there may be multiple UTF-8 representations of a given string. Since the key generated by a password-base key derivation function is dependent on the specific bytes, this matters a great deal.
Composed vs. Decomposed
Certain UTF-8 code points can be combined with other characters to create composed characters. For example, the letter a with the umlaut diacritic mark (two dots over it) can be expressed two ways; as its composed form, U+00FC; or its decomposed form, which is the letter "u" followed by U+0308 (which basically means modify the previous character by adding an umlaut to it).
// In the following two cases, a "u" with an umlaut would be seen > '\u00fc' > 'u\u0308' // In its composed form, it is 2 bytes long > new Buffer('u\u0308'.normalize('NFKC')) <Buffer c3 bc> > new Buffer('\u00fc') <Buffer c3 bc> // Whereas the decomposed form is 3 bytes, the letter u followed by U+0308 > new Buffer('\u00fc'.normalize('NFKD')) <Buffer 75 cc 88> > new Buffer('u\u0308') <Buffer 75 cc 88>
Compatibility equivalence mode
Certain strings are often displayed the same, even though they may have different semantic means. For example, UTF-8 provides a code point for the roman number for one, which appears as the letter I, in most fonts identically. Compatibility equivalence will fold these two cases into simply the capital letter I.
> '\u2160' 'I' > 'I' 'I' > '\u2160' === 'I' false > '\u2160'.normalize('NFKC') === 'I' true
normalize() method of a string can be used to convert a string to a
specific form. Without going into too much detail, I generally recommend
NFKC, however if you wish to dive deeper into this, a nice short summary
can be found in Pythons unicodedata module's
For browsers without
normalize() support, the npm unorm module
can be used to polyfill strings.
Another example of encoding woes
One quick story I will share is a project which used the
a key, which (ignoring rainbow table attacks)
had an unfortunate consequence of old web browsers replacing spaces with
+ while on new web
browsers, replacing it with a
%20, causing issues for anyone who used spaces in their password.
See: Unicode Equivalence
The test cases from the scrypt whitepaper are included in
test/test-vectors.json and can be run using:
Obviously, it's all licensed under the MIT license, so use it as you wish; but if you'd like to buy me a coffee, I won't complain. =)