Crypto
๐ High-security encryption/decryption library using AES-256-GCM and Argon2id for Node.js applications with full TypeScript support.

โจ Features
- ๐ AES-256-GCM authenticated encryption
- ๐ Argon2id memory-hard key derivation
- ๐ File streaming for large files
- ๐ก๏ธ Memory-safe operations with secure clearing
- โ
Strong password validation with detailed feedback
- ๐ Cross-platform compatibility
- ๐ Full TypeScript support with strict typing
- ๐งช Comprehensive testing with 80%+ coverage
- ๐ Modern ES modules with tree-shaking support
- ๐ Security-focused with constant-time comparisons
- ๐ Default passphrase support for simplified usage
๐ฆ Installation
npm install @hiprax/crypto
๐ Quick Start
Basic Usage
Asynchronous Operations (Recommended)
import { CryptoManager } from '@hiprax/crypto';
const crypto = new CryptoManager();
const encrypted = await crypto.encryptText(
'Hello World',
'MySecureP@ssw0rd123!'
);
console.log('Encrypted:', encrypted);
const decrypted = await crypto.decryptText(encrypted, 'MySecureP@ssw0rd123!');
console.log('Decrypted:', decrypted);
Synchronous Operations
For scenarios where you need synchronous operations (note: uses PBKDF2 instead of Argon2id for key derivation):
import { CryptoManager } from '@hiprax/crypto';
const crypto = new CryptoManager();
const encrypted = crypto.encryptTextSync('Hello World', 'MySecureP@ssw0rd123!');
console.log('Encrypted:', encrypted);
const decrypted = crypto.decryptTextSync(encrypted, 'MySecureP@ssw0rd123!');
console.log('Decrypted:', decrypted);
Using Default Passphrase
You can set a default passphrase when creating the CryptoManager instance, which allows you to encrypt and decrypt without specifying a password each time:
import { CryptoManager } from '@hiprax/crypto';
const crypto = new CryptoManager({
defaultPassphrase: 'MySecureP@ssw0rd123!',
});
const encrypted = await crypto.encryptText('Hello World');
console.log('Encrypted:', encrypted);
const decrypted = await crypto.decryptText(encrypted);
console.log('Decrypted:', decrypted);
const encryptedWithCustom = await crypto.encryptText(
'Hello World',
'CustomP@ssw0rd456!'
);
File Encryption
Asynchronous File Operations (Recommended)
import { CryptoManager } from '@hiprax/crypto';
const crypto = new CryptoManager();
await crypto.encryptFile('input.txt', 'output.enc', 'MySecureP@ssw0rd123!');
await crypto.decryptFile('output.enc', 'decrypted.txt', 'MySecureP@ssw0rd123!');
Synchronous File Operations
For scenarios where you need synchronous file operations (note: uses PBKDF2 instead of Argon2id for key derivation):
import { CryptoManager } from '@hiprax/crypto';
const crypto = new CryptoManager();
crypto.encryptFileSync('input.txt', 'output.enc', 'MySecureP@ssw0rd123!');
crypto.decryptFileSync('output.enc', 'decrypted.txt', 'MySecureP@ssw0rd123!');
File Encryption with Default Passphrase
Asynchronous Operations
import { CryptoManager } from '@hiprax/crypto';
const crypto = new CryptoManager({
defaultPassphrase: 'MySecureP@ssw0rd123!',
});
await crypto.encryptFile('input.txt', 'output.enc');
await crypto.decryptFile('output.enc', 'decrypted.txt');
await crypto.encryptFile('input.txt', 'output.enc', 'CustomP@ssw0rd456!');
Synchronous Operations
import { CryptoManager } from '@hiprax/crypto';
const crypto = new CryptoManager({
defaultPassphrase: 'MySecureP@ssw0rd123!',
});
crypto.encryptFileSync('input.txt', 'output.enc');
crypto.decryptFileSync('output.enc', 'decrypted.txt');
crypto.encryptFileSync('input.txt', 'output.enc', 'CustomP@ssw0rd456!');
Custom Configuration
import { CryptoManager } from '@hiprax/crypto';
const crypto = new CryptoManager({
memoryCost: 2 ** 18,
timeCost: 4,
parallelism: 2,
aad: 'my-app-v1',
});
console.log('Security Level:', crypto.getSecurityLevel());
๐ API Reference
CryptoManager
The main class for encryption/decryption operations.
Constructor
const crypto = new CryptoManager(options?: CryptoManagerOptions);
Options:
memoryCost
(number): Argon2 memory cost (default: 65536)
timeCost
(number): Argon2 time cost (default: 3)
parallelism
(number): Argon2 parallelism (default: 1)
aad
(string): Custom Additional Authenticated Data (default: 'secure-crypto-tool-v2')
defaultPassphrase
(string): Default passphrase to use when no password is provided to encryption/decryption methods
Methods
encryptText(text: string, password?: string): Promise<string>
Encrypts text with a password. If no password is provided and a default passphrase is set, the default passphrase will be used.
const encrypted = await crypto.encryptText(
'Hello World',
'MySecureP@ssw0rd123!'
);
const crypto = new CryptoManager({ defaultPassphrase: 'MySecureP@ssw0rd123!' });
const encrypted = await crypto.encryptText('Hello World');
decryptText(encryptedText: string, password?: string): Promise<string>
Decrypts text with a password. If no password is provided and a default passphrase is set, the default passphrase will be used.
const decrypted = await crypto.decryptText(encrypted, 'MySecureP@ssw0rd123!');
const crypto = new CryptoManager({ defaultPassphrase: 'MySecureP@ssw0rd123!' });
const decrypted = await crypto.decryptText(encrypted);
encryptTextSync(text: string, password?: string): string
Synchronous version of text encryption. Uses PBKDF2 for key derivation instead of Argon2id for synchronous operation.
const encrypted = crypto.encryptTextSync('Hello World', 'MySecureP@ssw0rd123!');
const crypto = new CryptoManager({ defaultPassphrase: 'MySecureP@ssw0rd123!' });
const encrypted = crypto.encryptTextSync('Hello World');
decryptTextSync(encryptedText: string, password?: string): string
Synchronous version of text decryption. Uses PBKDF2 for key derivation instead of Argon2id for synchronous operation.
const decrypted = crypto.decryptTextSync(encrypted, 'MySecureP@ssw0rd123!');
const crypto = new CryptoManager({ defaultPassphrase: 'MySecureP@ssw0rd123!' });
const decrypted = crypto.decryptTextSync(encrypted);
encryptFile(inputPath: string, outputPath: string, password?: string, progressCallback?: ProgressCallback): Promise<void>
Encrypts a file with a password. If no password is provided and a default passphrase is set, the default passphrase will be used.
await crypto.encryptFile('input.txt', 'output.enc', 'MySecureP@ssw0rd123!');
const crypto = new CryptoManager({ defaultPassphrase: 'MySecureP@ssw0rd123!' });
await crypto.encryptFile('input.txt', 'output.enc');
decryptFile(inputPath: string, outputPath: string, password?: string, progressCallback?: ProgressCallback): Promise<void>
Decrypts a file with a password. If no password is provided and a default passphrase is set, the default passphrase will be used.
await crypto.decryptFile('output.enc', 'decrypted.txt', 'MySecureP@ssw0rd123!');
const crypto = new CryptoManager({ defaultPassphrase: 'MySecureP@ssw0rd123!' });
await crypto.decryptFile('output.enc', 'decrypted.txt');
encryptFileSync(inputPath: string, outputPath: string, password?: string): void
Synchronous version of file encryption. Uses PBKDF2 for key derivation instead of Argon2id for synchronous operation.
crypto.encryptFileSync('input.txt', 'output.enc', 'MySecureP@ssw0rd123!');
const crypto = new CryptoManager({ defaultPassphrase: 'MySecureP@ssw0rd123!' });
crypto.encryptFileSync('input.txt', 'output.enc');
decryptFileSync(inputPath: string, outputPath: string, password?: string): void
Synchronous version of file decryption. Uses PBKDF2 for key derivation instead of Argon2id for synchronous operation.
crypto.decryptFileSync('output.enc', 'decrypted.txt', 'MySecureP@ssw0rd123!');
const crypto = new CryptoManager({ defaultPassphrase: 'MySecureP@ssw0rd123!' });
crypto.decryptFileSync('output.enc', 'decrypted.txt');
validatePassword(password: string): boolean
Validates password strength.
const isValid = crypto.validatePassword('MySecureP@ssw0rd123!');
generateSecureRandom(length: number): Buffer
Generates cryptographically secure random bytes.
const random = crypto.generateSecureRandom(32);
deriveKeySync(password: string, salt: Buffer): Buffer
Synchronous version of key derivation using PBKDF2 instead of Argon2id.
const salt = crypto.generateSecureRandom(32);
const key = crypto.deriveKeySync('MySecureP@ssw0rd123!', salt);
getParameters(): EncryptionParameters
Gets current encryption parameters.
const params = crypto.getParameters();
getSecurityLevel(): SecurityLevel
Gets security level based on configuration.
const level = crypto.getSecurityLevel();
hasDefaultPassphrase(): boolean
Checks if a default passphrase is configured.
const hasDefault = crypto.hasDefaultPassphrase();
Utility Functions
Additional utility functions are also exported:
import {
validateFile,
validatePath,
generateRandomString,
validatePasswordStrength,
generateUUID,
sha256,
generateRandomHex,
secureStringCompare,
formatFileSize,
isTextFile,
sanitizeFilename,
createBackupPath,
isValidBase64,
createProgressBar,
sleep,
retryWithBackoff,
getFileInfo,
} from '@hiprax/crypto';
const fileValidation = await validateFile('path/to/file.txt');
const pathValidation = validatePath('path/to/output.txt');
const randomString = generateRandomString(32);
const passwordCheck = validatePasswordStrength('MyPassword123!');
console.log('Score:', passwordCheck.score);
console.log('Feedback:', passwordCheck.feedback);
const uuid = generateUUID();
const hash = sha256('hello world');
const hex = generateRandomHex(16);
const isEqual = secureStringCompare('secret', 'secret');
const size = formatFileSize(1024 * 1024);
const isText = isTextFile('document.txt');
const safeName = sanitizeFilename('file<name>.txt');
const backupPath = createBackupPath('file.txt');
const isValid = isValidBase64('SGVsbG8gV29ybGQ=');
const progress = createProgressBar(50, 100);
await sleep(1000);
const result = await retryWithBackoff(
async () => {
return await someOperation();
},
{ maxRetries: 3, baseDelay: 1000 }
);
const fileInfo = await getFileInfo('path/to/file.txt');
console.log('Size:', fileInfo.size);
console.log('Extension:', fileInfo.extension);
console.log('Is Text:', fileInfo.isTextFile);
๐ง Configuration
Asynchronous vs Synchronous Operations
The library provides both asynchronous and synchronous versions of encryption/decryption operations:
Asynchronous Operations (Recommended)
- Use Argon2id for key derivation (more secure)
- Better for performance and scalability
- Non-blocking operations
- Methods:
encryptText()
, decryptText()
, encryptFile()
, decryptFile()
Synchronous Operations
- Use PBKDF2 for key derivation (less secure but synchronous)
- Blocking operations
- Useful for simple scripts or when async/await is not available
- Methods:
encryptTextSync()
, decryptTextSync()
, encryptFileSync()
, decryptFileSync()
Note: Synchronous operations use PBKDF2 with 100,000 iterations for security, but Argon2id is still recommended for production use.
Important: Synchronous and asynchronous functions are not compatible with each other due to different key derivation methods. Always use the same type (sync or async) for both encryption and decryption.
Security Levels
The library supports different security levels based on Argon2 parameters:
- Low:
memoryCost: 2^12, timeCost: 1
(Fast, less secure)
- Medium:
memoryCost: 2^14, timeCost: 2
(Balanced)
- High:
memoryCost: 2^16, timeCost: 3
(Default, secure)
- Ultra:
memoryCost: 2^18, timeCost: 4
(Maximum security)
Password Requirements
Passwords must meet the following criteria:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
๐ก๏ธ Security Features
Cryptographic Security
- AES-256-GCM: Authenticated encryption with Galois/Counter Mode
- Argon2id: Memory-hard key derivation function (winner of Password Hashing Competition)
- Secure Random: Uses Node.js
crypto.randomBytes()
for all random generation
- Constant-time Operations: Secure string comparison to prevent timing attacks
Memory Security
- Secure Clearing: Sensitive data is zeroed from memory after use
- No Memory Leaks: Proper cleanup of cryptographic materials
- Buffer Management: Safe handling of cryptographic buffers
Input Validation
- Path Sanitization: Prevents path traversal attacks
- Type Safety: Full TypeScript support prevents type-related vulnerabilities
- Parameter Validation: Comprehensive input validation with detailed error messages
๐งช Testing
Run the test suite:
npm test
Run tests with coverage:
npm run test:coverage
Run tests in watch mode:
npm run test:watch
๐ Error Handling
The library uses custom error types for better error handling:
import { CryptoError, CryptoErrorType } from '@hiprax/crypto';
try {
await crypto.encryptText('', '');
} catch (error) {
if (error instanceof CryptoError) {
console.log('Error Type:', error.type);
console.log('Error Code:', error.code);
console.log('Message:', error.message);
}
}
Error Types
INVALID_PASSWORD
: Password-related errors
INVALID_INPUT
: Invalid input parameters
ENCRYPTION_FAILED
: Encryption operation failures
DECRYPTION_FAILED
: Decryption operation failures
FILE_ERROR
: File system errors
MEMORY_ERROR
: Memory-related errors
VALIDATION_ERROR
: Validation failures
๐ฆ Development
Building
npm run build
Linting
npm run lint
npm run lint:fix
Formatting
npm run format
Type Checking
npm run type-check
๐ค Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
๐ License
MIT License - see LICENSE file for details.
๐ Links
โ ๏ธ Security Notice
This library is designed for security but should be used as part of a comprehensive security strategy. Always:
- Use strong, unique passwords
- Keep your dependencies updated
- Follow security best practices
- Consider additional security measures for critical applications
๐ Support
For support, please:
Made with โค๏ธ for secure applications