Last active
September 16, 2018 17:39
-
-
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`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this revision includes changes by @dchest suggested in dchest/scrypt-async-js#44 (comment)