Skip to content

Instantly share code, notes, and snippets.

@xfoxfu
Created September 24, 2018 07:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xfoxfu/a2803b293ade63b314fe7c9e5ea21cad to your computer and use it in GitHub Desktop.
Save xfoxfu/a2803b293ade63b314fe7c9e5ea21cad to your computer and use it in GitHub Desktop.
ASP.NET Core PBKDF2 Password Validation in Node.js
var crypto = require("crypto");
var hashedPassword = Buffer.from(
"AQAAAAEAACcQAAAAEPSiQdZVf3bivGCbaXPnuhozdt8k4cCphxfuc25NBGIioJV9deDyFK9awIow1HfR2A==",
"base64",
);
var password = Buffer.from("Admin888`");
const getPBKDF2Algorithm = prf => {
switch (prf) {
case 0:
return "sha1";
case 1:
return "sha256";
case 2:
return "sha512";
default:
throw new Error(`unsupported prf ${prf}`);
}
};
const getPBKDF2Params = hashedPasswordBytes => {
switch (hashedPasswordBytes[0]) {
/*
* Version 2:
* PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations.
* (See also: SDL crypto guidelines v5.1, Part III)
* Format: { 0x00, salt, subkey }
*/
case 0x00:
var salt = Buffer.alloc(16);
hashedPasswordBytes.copy(salt, 0, 1, 17);
var subkey = Buffer.alloc(32);
hashedPasswordBytes.copy(subkey, 0, 17, 49);
return {
hashAlgorithm: "sha1",
subkey,
salt,
iteration: 1000,
};
/*
* Version 3:
* PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 10000 iterations.
* Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
* (All UInt32s are stored big-endian.)
*/
case 0x01:
var prf = hashedPasswordBytes.readUInt32BE(1);
var iter = hashedPasswordBytes.readUInt32BE(5);
var saltLength = hashedPasswordBytes.readUInt32BE(9);
var salt = Buffer.alloc(saltLength);
hashedPasswordBytes.copy(salt, 0, 13, 13 + saltLength);
var subkey = Buffer.alloc(32);
hashedPasswordBytes.copy(
subkey,
0,
13 + saltLength,
13 + saltLength + 32,
);
return {
iteration: iter,
salt,
subkey,
hashAlgorithm: getPBKDF2Algorithm(prf),
};
default:
throw new Error(`invalid version ${hashedPasswordBytes[0].toString()}`);
}
};
var validate = (hash, password) => {
var data = getPBKDF2Params(hash);
return crypto
.pbkdf2Sync(
password,
data.salt,
data.iteration,
data.subkey.length,
data.hashAlgorithm,
)
.equals(data.subkey);
};
if (validate(hashedPassword, password)) {
console.info("passwords match!");
} else {
console.warn("passwords DO NOT match!");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment