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.
Maintainers
Readme
crypto-gate
Universal Cryptographic Toolkit — by Analytics With Harry · Squid Consultancy Group Limited
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 Hashing —
scrypt(memory-hard, superior to bcrypt) +PBKDF2-SHA512 - Symmetric Encryption —
AES-256-GCMauthenticated encryption - Asymmetric Encryption —
RSA-OAEP (SHA-256) - Digital Signatures —
ECDSA P-256andRSA-PSS - Hashing —
SHA-256 / 384 / 512,SHA3-256 / 512,BLAKE2b-512,BLAKE2s-256,MD5 - HMAC —
HMAC-SHA256 / SHA512and custom algorithms - Key Derivation —
scryptandPBKDF2 - Secure Tokens — UUID v4, OTP, API keys, recovery keys, random bytes
- Timing-safe comparison — prevents timing attacks on string comparisons
Installation
npm install crypto-gateRequires 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-DD73API 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); // falsePasswordHasher.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/decryptRSACipher
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); // booleanKeyDeriver
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 integerEncoder
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); // booleanFull 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:
scryptis 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
timingSafeEqualorHasher.comparewhen 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-gateLicense
MIT © Analytics With Harry - Squid Consultancy Group Limited
