Cryptix
A lightweight, cross-platform cryptographic library offering a unified API for modern security needs. This is the Node.js/JavaScript implementation — part of a multi-language suite ensuring identical behavior across ecosystems.
Overview
Cryptix provides enterprise-grade cryptographic primitives with a simple, developer-friendly API:
| Encryption | AES-256-GCM (authenticated) with PBKDF2 key derivation |
| Password Hashing | Argon2id (modern, memory-hard algorithm) |
| Legacy Hashing | SHA-256/SHA-512 via PBKDF2 with salt + pepper |
| Message Authentication | HMAC-SHA512 |
| Random Generation | Cryptographically secure keys and passwords |
Requirements
- Node.js 22.13.1 or higher
- Native ES modules support
Installation
npm install cryptix
Or with yarn:
yarn add cryptix
TypeScript type definitions are included.
Quick Start
import Cryptix from "cryptix";
const plaintext = "Sensitive data";
const password = "strong_password_123";
const encrypted = Cryptix.encrypt(plaintext, password);
const decrypted = Cryptix.decrypt(encrypted, password);
const hash = await Cryptix.argon2HashPassword(password);
const isValid = await Cryptix.argon2VerifyPassword(password, hash);
const hmac = Cryptix.generateHMAC("message", "secret");
const valid = Cryptix.verifyHMAC("message", "secret", hmac);
API Reference
Encryption & Decryption
Uses AES-256-GCM with PBKDF2-HMAC-SHA256 (10,000 iterations) for key derivation. Output format: Base64(salt + iv + ciphertext + authTag).
encrypt(plainText: string, password: string): string | Encrypts plaintext. Returns Base64 string. |
decrypt(encryptedText: string, password: string): string | Decrypts ciphertext. Returns plaintext. |
const encrypted = Cryptix.encrypt("Secret message", "myPassword");
const decrypted = Cryptix.decrypt(encrypted, "myPassword");
Password Hashing (Argon2id)
The recommended password hashing algorithm. Uses Argon2id with secure defaults. Output follows the PHC format.
argon2HashPassword(password: string): Promise<string> | Hash password using Argon2id. |
argon2VerifyPassword(password: string, hash: string): Promise<boolean> | Verify password against hash. |
argon2NeedsRehash(hash: string): boolean | Check if hash uses outdated parameters. |
const hash = await Cryptix.argon2HashPassword("userPassword");
const valid = await Cryptix.argon2VerifyPassword("userPassword", hash);
const shouldRehash = Cryptix.argon2NeedsRehash(hash);
Legacy Hashing (SHA-256 / SHA-512)
Uses PBKDF2 (10,000 iterations) with a random 64-byte salt and a server-side pepper. Format: Base64(salt)$Base64(hash).
generateSHA256Hash(input: string): string | Generate SHA-256 hash with salt + pepper. |
generateSHA512Hash(input: string): string | Generate SHA-512 hash with salt + pepper. |
hash256IsValid(hash: string, input: string): boolean | Verify SHA-256 hash. |
hash512IsValid(hash: string, input: string): boolean | Verify SHA-512 hash. |
const hash = Cryptix.generateSHA512Hash("password123");
const matches = Cryptix.hash512IsValid(hash, "password123");
HMAC-SHA512
generateHMAC(message: string, secretKey: string): string | Generate Base64-encoded HMAC-SHA512. |
verifyHMAC(message: string, secretKey: string, hmac: string): boolean | Constant-time verification. |
const hmac = Cryptix.generateHMAC("data", "secret_key");
const valid = Cryptix.verifyHMAC("data", "secret_key", hmac);
Key Derivation
generateKey(password: string, salt: Buffer): Buffer | Derive 256-bit AES key via PBKDF2. Returns 32-byte Buffer. |
generateSalt(): Buffer | Generate 16-byte cryptographically secure salt. |
Random Generation
generateRandomKey(): string | Generate 64-byte (512-bit) random key as Base64 string. |
generatePassword(length: number): string | Generate random password (alphanumeric + special). |
const key = Cryptix.generateRandomKey();
const pass = Cryptix.generatePassword(20);
File Encryption
Encrypt and decrypt files using AES-256-GCM.
encryptFile(inputPath: string, outputPath: string, password: string): void | Encrypt a file. |
decryptFile(inputPath: string, outputPath: string, password: string): void | Decrypt a file. |
encryptBytes(data: Buffer, password: string): string | Encrypt raw bytes. Returns Base64. |
decryptBytes(encoded: string, password: string): Buffer | Decrypt Base64-encoded bytes. |
Cryptix.encryptFile("./secret.txt", "./secret.enc", "password");
Cryptix.decryptFile("./secret.enc", "./decrypted.txt", "password");
const encrypted = Cryptix.encryptBytes(Buffer.from("data"), "password");
const decrypted = Cryptix.decryptBytes(encrypted, "password");
Complete Example — API Key Manager
import Cryptix from "cryptix";
import fs from "fs/promises";
class ApiKeyManager {
private storePath: string;
private masterPassword: string;
constructor(storePath: string, masterPassword: string) {
this.storePath = storePath;
this.masterPassword = masterPassword;
}
async storeApiKey(service: string, apiKey: string): Promise<void> {
const encryptedKey = Cryptix.encrypt(apiKey, this.masterPassword);
const serviceHash = Cryptix.generateSHA256Hash(service);
const store: Record<string, string> = {};
store[serviceHash] = encryptedKey;
await fs.writeFile(this.storePath, JSON.stringify(store, null, 2));
}
async retrieveApiKey(service: string): Promise<string | null> {
try {
const content = await fs.readFile(this.storePath, "utf-8");
const store = JSON.parse(content);
const serviceHash = Cryptix.generateSHA256Hash(service);
const encryptedKey = store[serviceHash];
return encryptedKey
? Cryptix.decrypt(encryptedKey, this.masterPassword)
: null;
} catch {
return null;
}
}
static generateMasterPassword(): string {
return Cryptix.generatePassword(24);
}
}
const manager = new ApiKeyManager("./keystore.json", "master_password_123");
await manager.storeApiKey("stripe", "sk_live_123456789");
const key = await manager.retrieveApiKey("stripe");
console.log("Retrieved:", key);
Security Considerations
Password Selection
- Use strong passwords with at least 12 characters
- Include uppercase, lowercase, numbers, and special symbols
- Use
Cryptix.generatePassword() for generating secure passwords
Pepper Management
The legacy hashing module uses a hardcoded pepper (SuperSecretPepperKey12345!). For production:
- Override via environment variable:
process.env.CRYPTIX_PEPPER
- Or modify the
PEPPER constant in HashingUtils.ts
Best Practices
- Each encryption generates a unique random salt and IV — never reuse passwords
- HMAC and hash verification use constant-time comparison to prevent timing attacks
- Use Argon2id for new password hashing (preferred over PBKDF2)
- All operations use Node.js native
crypto module
Cross-Language Compatibility
Cryptix produces identical outputs across all implementations. Data encrypted in one language can be decrypted in another.
| Node.js / TypeScript | Stable | npm install cryptix |
| Java | Stable | Maven: com.sec.cryptix |
| C++ | Stable | GitHub: c++ |
| Python | Planned | IN PROGRESS |
Performance
Typical performance on Node.js 22 / Intel i7-1260P:
encrypt() / decrypt() | 1 KB | ~0.8 ms |
encrypt() / decrypt() | 1 MB | ~12 ms |
argon2HashPassword() | N/A | ~100 ms |
generateSHA512Hash() | 256 bytes | ~15 ms |
generateHMAC() | 1 KB | ~0.3 ms |
Development
git clone https://gitlab.com/jesusmartinez70717/cryptix-lib.git
cd cryptix-lib/js
npm run compile
npm test
License
GPL-3.0 — See LICENSE file for details.
Support
Build secure systems. One API, every language.