npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

crypto-gate

v1.1.1

Published

Universal cryptographic toolkit — password hashing, AES-256-GCM, RSA, ECDSA, SHA3, BLAKE2, PBKDF2, scrypt, secure tokens. Zero external dependencies.

Readme

crypto-gate

Universal Cryptographic Toolkit — by Analytics With Harry · Squid Consultancy Group Limited

npm version License: MIT Node.js ≥15 Zero Dependencies


Why crypto-gate?

One package. Every crypto primitive you need. Zero external dependencies.

crypto-gate wraps Node.js's built-in crypto module into a clean, consistent API covering password hashing, symmetric/asymmetric encryption, digital signatures, hashing, key derivation, and secure token generation.

  • Password Hashingscrypt (memory-hard, superior to bcrypt) + PBKDF2-SHA512
  • Symmetric EncryptionAES-256-GCM authenticated encryption
  • Asymmetric EncryptionRSA-OAEP (SHA-256)
  • Digital SignaturesECDSA P-256 and RSA-PSS
  • HashingSHA-256 / 384 / 512, SHA3-256 / 512, BLAKE2b-512, BLAKE2s-256, MD5
  • HMACHMAC-SHA256 / SHA512 and custom algorithms
  • Key Derivationscrypt and PBKDF2
  • Secure Tokens — UUID v4, OTP, API keys, recovery keys, random bytes
  • Timing-safe comparison — prevents timing attacks on string comparisons

Installation

npm install crypto-gate

Requires Node.js ≥ 15.0.0.


Quick Start

const {
  PasswordHasher,
  AESCipher,
  Hasher,
  TokenGenerator,
} = require("crypto-gate");

// Hash a password
const hash = await PasswordHasher.hash("my-secret-password");
console.log(hash); // $cgscrypt$v1$32768$8$1$<salt>$<hash>

// Verify a password
const ok = await PasswordHasher.verify("my-secret-password", hash);
console.log(ok); // true

// AES-256-GCM encryption
const key = AESCipher.generateKey();
const encrypted = AESCipher.encrypt("Hello World", key);
const decrypted = AESCipher.decrypt(encrypted, key);

// Hashing
console.log(Hasher.sha256("data"));
console.log(Hasher.blake2b512("data"));

// Generate tokens
console.log(TokenGenerator.uuid()); // 550e8400-e29b-41d4-a716...
console.log(TokenGenerator.otp(6)); // 847291
console.log(TokenGenerator.apiKey("live")); // cg_live_3f7a...
console.log(TokenGenerator.recoveryKey()); // A3F2-88BC-4E19-DD73

API Reference

PasswordHasher

PasswordHasher.hash(password, [options])Promise<string>

Hashes a password using scrypt (memory-hard, NIST-recommended). Returns a self-contained encoded string that includes all parameters needed for verification.

const hash = await PasswordHasher.hash("myPassword", {
  N: 32768, // CPU/memory cost (power of 2, default: 32768)
  r: 8, // block size (default: 8)
  p: 1, // parallelisation (default: 1)
  keylen: 64, // output length in bytes (default: 64)
});
// "$cgscrypt$v1$32768$8$1$<salt_hex>$<hash_hex>"

PasswordHasher.verify(password, encoded)Promise<boolean>

Verifies a password against a previously computed hash. Uses timing-safe comparison.

const valid = await PasswordHasher.verify("myPassword", hash); // true
const wrong = await PasswordHasher.verify("wrongPassword", hash); // false

PasswordHasher.hashPBKDF2(password, [options])Promise<string>

Hashes using PBKDF2-SHA512 with 310,000 iterations (OWASP recommended).

const hash = await PasswordHasher.hashPBKDF2("myPassword", {
  iterations: 310000,
  keylen: 64,
  digest: "sha512",
});

PasswordHasher.verifyPBKDF2(password, encoded)Promise<boolean>

PasswordHasher.analyzeStrength(password){ score, strength, suggestions }

const result = PasswordHasher.analyzeStrength("P@ssw0rd!99");
// { score: 7, strength: 'Very Strong', suggestions: [] }

AESCipher

AESCipher.generateKey()string

Generates a cryptographically secure 256-bit (64 hex chars) AES key.

const key = AESCipher.generateKey(); // "a1b2c3d4..."

AESCipher.encrypt(data, key)string

Encrypts using AES-256-GCM authenticated encryption. Output format: <iv_hex>:<tag_hex>:<ciphertext_hex>.

const key = AESCipher.generateKey();
const encrypted = AESCipher.encrypt("sensitive data", key);

AESCipher.decrypt(payload, key)string

const plaintext = AESCipher.decrypt(encrypted, key);

AESCipher.deriveKey(passphrase, [salt])Promise<{ key, salt }>

Derives a 256-bit AES key from a passphrase using scrypt.

const { key, salt } = await AESCipher.deriveKey("my-passphrase");
// Store salt alongside ciphertext; use key for encrypt/decrypt

RSACipher

RSACipher.generateKeyPair([modulusLength])Promise<{ publicKey, privateKey }>

const { publicKey, privateKey } = await RSACipher.generateKeyPair(4096);

RSACipher.encrypt(data, publicKey)string

Encrypts using RSA-OAEP (SHA-256). Returns base64.

RSACipher.decrypt(ciphertext, privateKey)string


Signer

Signer.generateECDSAKeyPair()Promise<{ publicKey, privateKey }>

Generates ECDSA P-256 (secp256r1) key pair. Fast and compact signatures.

Signer.ecSign(data, privateKey)string

Signs with ECDSA-SHA256. Returns base64.

Signer.ecVerify(data, signature, publicKey)boolean

Signer.generateRSAKeyPair([modulusLength])Promise<{ publicKey, privateKey }>

Signer.rsaSign(data, privateKey)string

Signs with RSA-PSS-SHA256. Returns base64.

Signer.rsaVerify(data, signature, publicKey)boolean


Hasher

Hasher.sha256("data"); // hex
Hasher.sha512("data"); // hex
Hasher.sha384("data"); // hex
Hasher.sha3_256("data"); // hex
Hasher.sha3_512("data"); // hex
Hasher.blake2b512("data"); // hex
Hasher.blake2s256("data"); // hex
Hasher.md5("data"); // hex (legacy only)

// Optional encoding: 'hex', 'base64', 'buffer'
Hasher.sha256("data", "base64");
Hasher.sha256("data", "buffer"); // Buffer

// HMAC
Hasher.hmacSHA256("data", "secret-key");
Hasher.hmacSHA512("data", "secret-key");
Hasher.hmac("data", "key", "sha384", "hex");

// Timing-safe comparison
Hasher.compare(hashA, hashB); // boolean

KeyDeriver

KeyDeriver.scrypt(input, [salt], [options])Promise<{ key, salt }>

const { key, salt } = await KeyDeriver.scrypt("secret", null, {
  keylen: 32,
  N: 65536,
});
// Later: re-derive with same salt to verify
const { key: key2 } = await KeyDeriver.scrypt("secret", salt, {
  keylen: 32,
  N: 65536,
});

KeyDeriver.pbkdf2(input, [salt], [options])Promise<{ key, salt }>


TokenGenerator

TokenGenerator.random(32, "hex"); // 64-char hex token
TokenGenerator.random(32, "base64"); // base64 token
TokenGenerator.random(32, "base64url"); // URL-safe base64

TokenGenerator.uuid(); // "550e8400-e29b-41d4-a716-446655440000"
TokenGenerator.otp(6); // "847291"
TokenGenerator.otp(8); // "38472916"

TokenGenerator.apiKey("live"); // "cg_live_3f7a8b9c..."
TokenGenerator.apiKey("test"); // "cg_test_a1b2c3d4..."

TokenGenerator.recoveryKey(4); // "A3F2-88BC-4E19-DD73"
TokenGenerator.recoveryKey(6); // "A3F2-88BC-4E19-DD73-F2A1-93BC"

TokenGenerator.bytes(16); // Buffer(16) — raw random bytes
TokenGenerator.randomInt(1, 100); // secure random integer

Encoder

Encoder.toBase64("hello"); // 'aGVsbG8='
Encoder.fromBase64("aGVsbG8="); // 'hello'
Encoder.toBase64Url("hello world"); // URL-safe base64
Encoder.fromBase64Url(str);
Encoder.toHex("hello"); // '68656c6c6f'
Encoder.fromHex("68656c6c6f"); // 'hello'
Encoder.bufferToHex(buf);
Encoder.hexToBuffer(hexStr);

timingSafeEqual(a, b)boolean

Exported utility for constant-time string comparison (prevents timing attacks).

const { timingSafeEqual } = require("crypto-gate");
timingSafeEqual(userHash, storedHash); // boolean

Full Example

const {
  PasswordHasher,
  AESCipher,
  RSACipher,
  Signer,
  Hasher,
  KeyDeriver,
  TokenGenerator,
  Encoder,
} = require("crypto-gate");

async function demo() {
  // --- Password Hashing ---
  const hash = await PasswordHasher.hash("MySecretP@ss!");
  console.log("Hash:", hash);
  console.log("Valid:", await PasswordHasher.verify("MySecretP@ss!", hash));

  const strength = PasswordHasher.analyzeStrength("MySecretP@ss!");
  console.log("Strength:", strength.strength, "| Score:", strength.score);

  // --- AES Encryption ---
  const key = AESCipher.generateKey();
  const enc = AESCipher.encrypt(
    JSON.stringify({ userId: 42, role: "admin" }),
    key,
  );
  const dec = AESCipher.decrypt(enc, key);
  console.log("Decrypted:", dec);

  // --- RSA ---
  const { publicKey, privateKey } = await RSACipher.generateKeyPair(2048);
  const rsaEnc = RSACipher.encrypt("top secret", publicKey);
  const rsaDec = RSACipher.decrypt(rsaEnc, privateKey);
  console.log("RSA decrypted:", rsaDec);

  // --- ECDSA Signing ---
  const ecKeys = await Signer.generateECDSAKeyPair();
  const sig = Signer.ecSign(
    '{"action":"transfer","amount":100}',
    ecKeys.privateKey,
  );
  console.log(
    "Signature valid:",
    Signer.ecVerify(
      '{"action":"transfer","amount":100}',
      sig,
      ecKeys.publicKey,
    ),
  );

  // --- Hashing ---
  console.log("SHA-256:", Hasher.sha256("hello world"));
  console.log("BLAKE2b:", Hasher.blake2b512("hello world"));
  console.log("HMAC:", Hasher.hmacSHA256("message", "secret"));

  // --- Tokens ---
  console.log("UUID:", TokenGenerator.uuid());
  console.log("OTP:", TokenGenerator.otp(6));
  console.log("API Key:", TokenGenerator.apiKey("prod"));
  console.log("Recovery:", TokenGenerator.recoveryKey());
}

demo().catch(console.error);

Security Notes

  • scrypt vs bcrypt: scrypt is memory-hard and more resistant to GPU/ASIC attacks than bcrypt. It is the recommended choice for password hashing in modern applications.
  • AES-256-GCM: Provides both confidentiality and integrity (authenticated encryption). The auth tag prevents tampering.
  • RSA-OAEP: Secure asymmetric encryption. Never use RSA-PKCS1v1.5 for new systems.
  • ECDSA P-256: Compact, fast, widely supported. Equivalent security to RSA-3072.
  • Timing-safe comparison: Always use timingSafeEqual or Hasher.compare when comparing secrets to prevent timing attacks.

Python Package

A companion Python implementation (crypto-gate) is available on PyPI with the same API structure, using only Python standard library modules (hashlib, hmac, secrets).

pip install crypto-gate

License

MIT © Analytics With Harry - Squid Consultancy Group Limited