Skip to content

Instantly share code, notes, and snippets.

@ccoenen
Last active September 16, 2018 17:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ccoenen/3b228a32790ad0a5e1b29adfde963e96 to your computer and use it in GitHub Desktop.
Save ccoenen/3b228a32790ad0a5e1b29adfde963e96 to your computer and use it in GitHub Desktop.
I am trying to read "old" node-scrypt hashes with scrypt-async. So far with little success. This script needs `scrypt` and `scrypt-async` installed via `npm`
/* ATTEMPT TO PARSE A node-scrypt STRING CORRECTLY FOR USE WITH scrypt-async */
var scrypt = require('scrypt-async');
var scryptOld = require('scrypt');
var crypto = require('crypto');
// Format as seen in node-scrypt, written by Barry Steyn. Scrypt by Colin Percival.
// https://github.com/barrysteyn/node-scrypt/blob/master/scrypt/scrypt-1.2.0/keyderivation.c#L60-L77 and
// https://security.stackexchange.com/a/91050/50616
// scrypt paper: https://www.tarsnap.com/scrypt/scrypt.pdf (not helpful for this :-( )
function parseScrypt(hexString) {
var b = Buffer.from(hexString, "hex");
var sha256 = crypto.createHash('SHA256');
if (b.toString("ASCII", 0, 6) !== 'scrypt') {
throw "this is not scrypt";
}
var parsed = {
first64bytes: b.slice(0, 64),
logN: b.readUInt8(7),
r: b.readUInt32BE(8),
p: b.readUInt32BE(12),
salt: b.slice(16, 48),
checksum: b.slice(48, 64),
signature: b.slice(64, 96)
};
sha256.update(b.slice(0, 48));
var digest = sha256.digest().slice(0, 16);
if (Buffer.compare(digest, parsed.checksum) !== 0) {
throw "something is odd while parsing: checksums do not match";
}
return parsed;
}
// testing: this generates a hash from node-scrypt.
var hash = scryptOld.kdfSync("hello", scryptOld.paramsSync(0.1)).toString("hex");
// we'll parse it using our function from above.
var scryptParams = parseScrypt(hash);
console.log(scryptParams);
console.log("-> original: %s", scryptParams.signature.toString("hex"));
// let's see if we can verify it! This means recreating a hash with the same parameters and trying to get the same result.
scrypt(Buffer.from("hello", "UTF-8"), scryptParams.salt, {
logN: scryptParams.logN,
r: scryptParams.r,
p: scryptParams.p,
dkLen: 64, // **** CHANGED ***
encoding: "binary" // *** CHANGED ***
}, function (key) {
// ***** ADDED ****
var hmacKey = key.subarray(32);
var result = crypto.createHmac('sha256', hmacKey).update(scryptParams.first64bytes).digest("hex");
console.log("-> comparison: %s", result);
});
@ccoenen
Copy link
Author

ccoenen commented Sep 16, 2018

this revision includes changes by @dchest suggested in dchest/scrypt-async-js#44 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment