Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Scrypt for Node/IO is a native node/io C++ wrapper for Colin Percival's scrypt cryptographic hash utility.
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.
Version 5 is a major new release that is not backward compatible with any previous version. Some highlights:
Version 5 is not backward compatible, but it should still be easy to migrate. Please read the api section to see what's changed. One big change that is worth noting is a name change: What used to be called hash has now been changed to kdf and conversely, what was kdf is now called hash.
Scrypt is an advanced crypto library used mainly for key derivation: More information can be found here:
Node-gyp is needed to build this module. It should be installed globally, that is, with the -g
switch:
npm install -g node-gyp
npm install scrypt
git clone https://github.com/barrysteyn/node-scrypt.git
cd node-scrypt
npm install
node-gyp configure build
To test, go to the folder where scrypt was installed, and type:
npm test
Translates human understandable parameters to scrypt's internal parameters.
scrypt.paramsSync
scrypt.params(maxtime, [maxmem, [max_memfrac]], [function(err, obj) {}])
Note: In previous versions, this was called hash.
Produces a key derivation function that uses the scrypt hash function. This should be used for hashing and checking passwords as it incorporates salt as well as HMAC into its format. It is based on a design by Colin Percival, the author of scrypt. The format can be seen here.
scrypt.kdfSync
scrypt.kdf(key, paramsObject, [function(err, obj){}])
Checks if a key (password) matches a kdf.
scrypt.verifyKdfSync
scrypt.verifyKdf(kdf, key, [function(err, result){}])
Note: In previous versions, this was called kdf.
This is the raw scrypt hash function.
scrypt.hashSync
scrypt.hash(key, paramsObject, output_length, function(err, obj){})
var scrypt = require("scrypt");
//Synchronous
try {
//Uses 0.1 for maxtime, and default values maxmem and maxmemfrac
var scryptParameters = scrypt.paramsSync(0.1);
console.log(scryptParameters);
} catch(err) {
//handle error
}
//Asynchronous with callback
scrypt.params(0.1, function(err, scryptParameters) {
console.log(scryptParameters);
});
//Asynchronous with promise
scrypt.params(0.1).then(function(result){
console.log(result);
}, function(err) {
console.log(err);
});
var scrypt = require("scrypt");
var scryptParameters = scrypt.paramsSync(0.1);
var key = new Buffer("this is a key"); //could also be a string
//Synchronous example that will output in hexidecimal encoding
var kdfResult = scrypt.kdfSync(key, scryptParameters); //should be wrapped in try catch, but leaving it out for brevity
console.log("Synchronous result: "+kdfResult.toString("hex"));
//Asynchronous example that expects key to be ascii encoded
scrypt.kdf("ascii encoded key", {N: 1, r:1, p:1}, function(err, result){
//Note how scrypt parameters was passed as a JSON object
console.log("Asynchronous result: "+result.toString("base64"));
});
//Asynchronous with promise
scrypt.kdf("ascii encoded key", {N: 1, r:1, p:1}).then(function(result){
console.log("Asynchronous result: "+result.toString("base64"));
}, function(err){
});
var scrypt = require("scrypt");
var scryptParameters = scrypt.paramsSync(0.1);
var kdfResult = scrypt.kdfSync("password", scryptParameters);
//Synchronous
scrypt.verifyKdfSync(kdfResult, "password"); // returns true
scrypt.verifyKdfSync(kdfResult, "incorrect password"); // returns false
//Asynchronous
scrypt.verifyKdf(kdfResult, new Buffer("password"), function(err, result) {
//result will be true
});
//Asynchronous with promise
scrypt.verifyKdf(kdfResult, "incorrect password").then(function(result) {
//result will be false
}, function(err) {
});
The scrypt paper lists four test vectors to test implementation. This example will show how to produce these test vectors from within this module.
var scrypt = require("scrypt");
var key = new Buffer("");
//Synchronous
var result = scrypt.hashSync(key,{"N":16,"r":1,"p":1},64,"");
console.log(result.toString("hex"));
//Asynchronous
scrypt.hash(key, {"N":16,"r":1,"p":1},64,"", function(err, res) {
console.log(result.toString("hex"));
});
//Asynchronous with promise
scrypt.hash(key, {"N":16,"r":1,"p":1},64,"").then(function(result) {
console.log(result.toString("hex"));
}, function(err){});
var scrypt = require("scrypt");
var salt = new Buffer("NaCl");
//Synchronous
var result = scrypt.hashSync("password", {"N":1024,"r":8,"p":16}, 64, salt);
console.log(result.toString("hex"));
scrypt.hash("password", {"N":1024,"r":8,"p":16},64,salt, function(err, result) {
console.log(result.toString("hex"));
});
var scrypt = require("scrypt");
var key = new Buffer("pleaseletmein");
var salt = new Buffer("SodiumChloride");
//Synchronous
var result = scrypt.hashSync(key,{"N":16384,"r":8,"p":1},64,salt);
console.log(result.toString("hex"));
//Asynchronous
scrypt.hash(key, {"N":16384,"r":8,"p":1}, 64, salt, function(err, result) {
console.log(result.toString("hex"));
});
Note: This test vector is very taxing in terms of resources.
var scrypt = require("scrypt");
//Synchronous
var result = scrypt.hashSync("pleaseletmein",{"N":1048576,"r":8,"p":1},64,"SodiumChloride");
console.log(result.toString("hex"));
//Asynchronous
scrypt.hash("pleaseletmein", {"N":1048576,"r":8,"p":1},64,"SodiumChloride", function(err, result) {
console.log(result.toString("hex"));
});
This module supports most posix platforms, as well as Microsoft Windows. It has been tested on the following platforms: Linux, MAC OS, SmartOS (so its ready for Joyent Cloud) and Microsoft Windows. It also works on FreeBSD, OpenBSD, SunOS etc.
It is probably the most advanced key derivation function available. This is is quote taken from a comment in hacker news:
Passwords hashed with scrypt with sufficiently-high strength values (there are 3 tweakable input numbers) are fundamentally impervious to being cracked. I use the word "fundamental" in the literal sense, here; even if you had the resources of a large country, you would not be able to design any hardware (whether it be GPU hardware, custom-designed hardware, or otherwise) which could crack these hashes. Ever. (For sufficiently-small definitions of "ever". At the very least "within your lifetime"; probably far longer.)
I will end this section with a quote from Colin Percival (author of scrypt):
We estimate that on modern (2009) hardware, if 5 seconds are spent computing a derived key, the cost of a hardware brute-force attack against scrypt is roughly 4000 times greater than the cost of a similar attack against bcrypt (to find the same password), and 20000 times greater than a similar attack against PBKDF2.
There is just one con I can think of: It is a relatively new library (only been around since 2009). Cryptographers don't really like new libraries for production deployment as it has not been battle tested. That being said, it is being actively used in Tarsnap (as mentioned above) and the author is very active.
Storing passwords requires three essential properties
As an example of how storing passwords can be done badly, take LinkedIn. In 2012, they came under fire for using unsalted hashes to store their passwords. As most commentators at the time were focusing no salt being present, the big picture was missed. In fact, their biggest problem was that they used sha1, a very fast hash function.
The kdf has a specific format: The word "scrypt" is added as a prefix. The reason for this is because I am sticking to Colin Percival's (the creator of scrypt) reference implementation, whereby he prefixes scrypt in this way. The base64 encoding of the ascii "scrypt" is c2NyeXB0. The scrypt parameters are then appended. Users of scrypt normally do not change this information once it is settled upon (hence this will also look the be identical).
To illustrate with an example, I have hashed two password: password1 and password2. Their Base64 outputs are as follows:
password1
c2NyeXB0AAwAAAAIAAAAAcQ0zwp7QNLklxCn14vB75AYWDIrrT9I/7F9+lVGBfKN/1TH2hs
/HboSy1ptzN0YzHJhC7PZIEPQzf2nuoaqVZg8VkKEJlo8/QaH7qjU2VwB
password2
c2NyeXB0AAwAAAAIAAAAAZ/+bp8gWcTZgEC7YQZeLLyxFeKRRdDkwbaGeFC0NkdUr/YFAWY
/UwdOH4i/PxW48fXeXBDOTvGWtS3lLUgzNM0PlJbXhMOGd2bke0PvTSnW
As one can see from the above example, both hashes start off by looking similar (they both start with c2NyeXB0AAwAAAAIAAAAA - as explained above), but after this, things change very rapidly. In fact, I hashed the password password1 again:
password1
c2NyeXB0AAwAAAAIAAAAATpP+fdQAryDiRmCmcoOrZa2mZ049KdbA/ofTTrATQQ+m
0L/gR811d0WQyip6p2skXVEMz2+8U+xGryFu2p0yzfCxYLUrAaIzaZELkN2M6k0
Compare this hash to the one above. Even though they start off looking similar, their outputs are vastly different (even though it is the same password being hashed). This is because of the random salt that has been added, ensuring that no two hashes will ever be identical, even if the password that is being hashed is the same.
For those that are curious or paranoid, please look at how the kdf is both produced and verified (you are going to need some knowledge of the C language for this).
Colin Percival has released a new version of scrypt, the first new version in five years. While it is not more secure than the current version, it does allow things to be done with more ease (like support for other platforms).
The scrypt library is Colin Percival's scrypt project.
Syed Beparey was instrumental in getting the Windows build working, with most of the Windows build based off the work done by Dinesh Shanbhag.
[5.2.0] - 2015-10-06
FAQs
The scrypt crypto library for NodeJS
The npm package scrypt receives a total of 5,150 weekly downloads. As such, scrypt popularity was classified as popular.
We found that scrypt demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.