Skip to content

Instantly share code, notes, and snippets.

@xfoxfu
Created September 24, 2018 07:51
Show Gist options
  • Save xfoxfu/a2803b293ade63b314fe7c9e5ea21cad to your computer and use it in GitHub Desktop.
Save xfoxfu/a2803b293ade63b314fe7c9e5ea21cad to your computer and use it in GitHub Desktop.

Revisions

  1. 小傅Fox created this gist Sep 24, 2018.
    86 changes: 86 additions & 0 deletions pbkdf2.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,86 @@
    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!");
    }