All free skills / Other majors

bcryptjs 2.x

Hash and compare asynchronously with explicit UTF-8 byte limits and stored cost inspection.

For
bcryptjs@2.4.3
Verified
2026-10-10, 7 examples executed
Skill package
@modootoday/pmcp-bcryptjs@2.0.0

Use this skill for free

No PMCP login or subscription is required. Download the original instructions, or install the content-only archive with your project's package manager.

Download SKILL.md · Download package archive

npm install --save-dev https://pmcp.build/skills/bcryptjs/2/package.tgz

PMCP discovers the installed package's instructions. Connect your runtime after installation.

Archive integritysha512-lnvVRR90F0A6IEQ5r++bhrEWyLrfMrSmWW5i5Nj7wlvPFBaiad4zLLf7bCZkenv8rWIQ2/uSJd7cUZhlOIkAvw==

Complete instructions

bcryptjs 2.x

Use this skill for bcryptjs 2.x, especially the observed 2.4.3 release. Inspect the installed version before using examples from the current upstream branch. V2 does not provide the newer bcrypt.truncates() helper.

Enforce the byte limit before hashing

Bcrypt accepts at most 72 input bytes. Count UTF-8 bytes, not JavaScript string length; multibyte passwords can exceed the limit with fewer than 72 characters. Reject an oversized input explicitly rather than silently accepting a truncated password. Apply the same input policy before comparison.

function validatePassword(password) {
  if (typeof password !== "string") {
    throw new TypeError("Password must be a string");
  }
  if (Buffer.byteLength(password, "utf8") > 72) {
    throw new RangeError("Password exceeds bcrypt's 72-byte limit");
  }
  return password;
}

Keep minimum length, normalization and acceptance rules in the application's password policy. Introducing a new preprocessing rule for existing hashes can make the original password fail comparison; do not change that contract silently during a library upgrade.

Use async operations and preserve the encoded hash

const bcrypt = require("bcryptjs");

async function createPasswordHash(password, workFactor) {
  return bcrypt.hash(validatePassword(password), workFactor);
}

async function passwordMatches(password, storedHash) {
  return bcrypt.compare(validatePassword(password), storedHash);
}

Pass a measured application work factor; omitting a callback selects the Promise API. Passing a numeric work factor to hash generates a fresh random salt. Store the complete encoded hash, which includes the salt and cost, and compare with bcrypt.compare rather than hashing again and comparing strings. Do not log plaintext passwords or substitute an insecure random fallback.

Async calls yield between portions of CPU work, but hashing still consumes CPU. Bound concurrent login/hash operations and benchmark the actual deployment. Cost 4 in a small local fixture reduces test time; it is not an operating recommendation for password storage.

Make rehash a verified-login decision

Read bcrypt.getRounds(storedHash) to inspect its cost. After a successful comparison, the application can create a new hash if its current policy calls for a higher cost, then persist it with normal concurrency safeguards. Do not rehash a supplied password after a failed comparison, or downgrade a stronger stored cost merely because the default changed.

Useful bounded checks are async hash/compare success and failure, encoded cost, exactly 72 UTF-8 bytes, oversized ASCII/multibyte input and non-string input. These checks establish local library behavior; they do not evaluate password policy strength, authentication rate limits or database persistence.

Sources