@happyvertical/encryption
Unified encryption and cryptography operations with adapter-based architecture supporting PGP, NaCl, and Node.js crypto.
Featuresโ
- ๐ Multiple Encryption Methods: PGP/OpenPGP, NaCl/libsodium, Node.js crypto
- ๐ Text, Files & Buffers: Encrypt any data format with a unified API
- ๐ง Email Integration: Specialized PGP/MIME email encryption
- ๐ Key Management: Generate, import, export, and manage encryption keys
- โ๏ธ Digital Signatures: Sign and verify data with RSA, ECDSA, and EdDSA
- ๐ฏ Type-Safe: Full TypeScript support with comprehensive type definitions
- โก High Performance: Fast NaCl encryption, efficient streaming for large files
- ๐งช Well-Tested: 209 tests covering all adapters and use cases
Installationโ
npm install @happyvertical/encryption
# or
pnpm add @happyvertical/encryption
# or
yarn add @happyvertical/encryption
Claude Code Contextโ
Install Claude Code context files for AI-assisted development:
npx have-encryption-context
This copies the package's AGENT.md documentation and metadata.json metadata to your project's .claude/ directory, enabling Claude to provide better assistance when working with this package.
Quick Startโ
PGP Encryptionโ
import { getEncryption } from '@happyvertical/encryption';
// Create PGP encryption instance
const pgp = await getEncryption({ type: 'pgp' });
// Generate keypair
const keypair = await pgp.generateKeyPair({
name: 'Alice',
email: 'alice@example.com',
passphrase: 'secure-passphrase',
type: 'rsa',
keySize: 4096
});
// Initialize with keys
const encryption = await getEncryption({
type: 'pgp',
publicKey: keypair.publicKey,
privateKey: keypair.privateKey,
passphrase: 'secure-passphrase'
});
// Encrypt and decrypt text
const encrypted = await encryption.encryptText('Secret message');
const decrypted = await encryption.decryptText(encrypted);
// Encrypt and decrypt files
await encryption.encryptFile('document.pdf', 'document.pdf.pgp');
await encryption.decryptFile('document.pdf.pgp', 'document.pdf');
NaCl Encryption (Fast & Modern)โ
import { getEncryption } from '@happyvertical/encryption';
// Generate keypair
const nacl = await getEncryption({ type: 'nacl' });
const keypair = await nacl.generateKeyPair();
// Symmetric encryption (secretbox)
const encryption = await getEncryption({
type: 'nacl',
secretKey: keypair.secretKey
});
const encrypted = await encryption.encryptText('Secret message');
const decrypted = await encryption.decryptText(encrypted);
// Encrypt files (very fast!)
await encryption.encryptFile('data.json', 'data.json.enc');
await encryption.decryptFile('data.json.enc', 'data.json');
Node.js Crypto (AES & RSA)โ
import { getEncryption } from '@happyvertical/encryption';
// AES-256-GCM encryption
const aes = await getEncryption({
type: 'node',
algorithm: 'aes-256-gcm',
keyDerivation: {
password: 'user-password',
salt: 'unique-salt',
iterations: 100000
}
});
const encrypted = await aes.encryptText('Secret message');
const decrypted = await aes.decryptText(encrypted);
// RSA encryption
const rsa = await getEncryption({
type: 'node',
algorithm: 'rsa-oaep'
});
const keypair = await rsa.generateKeyPair({
type: 'rsa',
keySize: 2048
});
const rsaEncryption = await getEncryption({
type: 'node',
algorithm: 'rsa-oaep',
publicKey: keypair.publicKey,
privateKey: keypair.privateKey
});
const encrypted = await rsaEncryption.encryptText('Small message');
const decrypted = await rsaEncryption.decryptText(encrypted);
Common Use Casesโ
Email Encryption (PGP/MIME)โ
import { getEncryption } from '@happyvertical/encryption';
const pgp = await getEncryption({
type: 'pgp',
publicKey: recipientPublicKey,
privateKey: myPrivateKey,
passphrase: 'my-passphrase'
});
// Encrypt email message
const encryptedEmail = await pgp.encryptEmail({
from: { address: 'sender@example.com' },
to: [{ address: 'recipient@example.com' }],
subject: 'Confidential Information',
text: 'Secret message content',
attachments: [
{ filename: 'document.pdf', content: pdfBuffer }
]
}, {
sign: true,
armor: true
});
// Send with your email provider
// await mailbox.send(encryptedEmail);
Database Field Encryptionโ
import { getEncryption } from '@happyvertical/encryption';
const encryption = await getEncryption({
type: 'node',
algorithm: 'aes-256-gcm',
keyDerivation: {
password: process.env.DB_ENCRYPTION_PASSWORD,
salt: 'db-encryption-salt',
iterations: 100000
}
});
// Encrypt sensitive fields
async function saveUser(user) {
const encryptedSSN = await encryption.encryptText(user.ssn);
const encryptedCreditCard = await encryption.encryptText(user.creditCard);
await db.insert('users', {
id: user.id,
name: user.name, // Plain text
ssn: encryptedSSN,
credit_card: encryptedCreditCard
});
}
// Decrypt when retrieving
async function getUser(id) {
const row = await db.selectOne('users', { where: { id } });
return {
id: row.id,
name: row.name,
ssn: await encryption.decryptText(row.ssn),
creditCard: await encryption.decryptText(row.credit_card)
};
}
File Backup Encryptionโ
import { getEncryption } from '@happyvertical/encryption';
const encryption = await getEncryption({
type: 'nacl',
secretKey: backupSecretKey
});
// Encrypt backup files
await encryption.encryptFile(
'/data/backup-2024-01.tar.gz',
'/encrypted-backups/backup-2024-01.tar.gz.enc'
);
// Decrypt when needed
await encryption.decryptFile(
'/encrypted-backups/backup-2024-01.tar.gz.enc',
'/restored/backup-2024-01.tar.gz'
);
Digital Signaturesโ
import { getEncryption } from '@happyvertical/encryption';
const pgp = await getEncryption({
type: 'pgp',
privateKey: myPrivateKey,
passphrase: 'my-passphrase'
});
// Sign message
const message = 'Important announcement';
const signature = await pgp.sign(message, {
detached: true,
armor: true
});
// Verify signature
const valid = await pgp.verify(message, signature, {
publicKey: signerPublicKey
});
if (valid) {
console.log('โ Signature verified - message is authentic');
} else {
console.log('โ Invalid signature - message may be tampered');
}
API Overviewโ
Factory Functionโ
function getEncryption(options: GetEncryptionOptions): Promise<Encryption>
Encryption Interfaceโ
All adapters implement this unified interface:
interface Encryption {
// Text operations
encryptText(text: string, options?: EncryptOptions): Promise<string>;
decryptText(encrypted: string, options?: DecryptOptions): Promise<string>;
// File operations
encryptFile(inputPath: string, outputPath: string, options?: EncryptOptions): Promise<void>;
decryptFile(inputPath: string, outputPath: string, options?: DecryptOptions): Promise<void>;
// Buffer operations
encryptBuffer(buffer: Buffer, options?: EncryptOptions): Promise<Buffer>;
decryptBuffer(buffer: Buffer, options?: DecryptOptions): Promise<Buffer>;
// Key management
generateKeyPair(options?: KeyPairOptions): Promise<KeyPair>;
importKey(key: string | Buffer, options?: ImportKeyOptions): Promise<Key>;
exportKey(key: Key, options?: ExportKeyOptions): Promise<string | Buffer>;
// Signing (optional)
sign?(data: string | Buffer, options?: SignOptions): Promise<string | Buffer>;
verify?(data: string | Buffer, signature: string | Buffer, options?: VerifyOptions): Promise<boolean>;
// Email operations (PGP only)
encryptEmail?(message: EmailMessage, options?: EncryptEmailOptions): Promise<EmailMessage>;
decryptEmail?(message: EmailMessage, options?: DecryptEmailOptions): Promise<DecryptedEmail>;
// Adapter info
getCapabilities(): Promise<EncryptionCapabilities>;
getAdapter(): AdapterType;
}
Adapter Comparisonโ
| Feature | PGP | NaCl | Node Crypto |
|---|---|---|---|
| Text Encryption | โ | โ | โ |
| File Encryption | โ | โ | โ |
| Email Encryption | โ | โ | โ |
| Digital Signatures | โ | โ | โ |
| Multiple Recipients | โ | โ | โ |
| Symmetric | โ | โ | โ |
| Asymmetric | โ | โ | โ |
| Speed | Medium | Fast | Fast |
| Key Size | Large | Small | Medium |
| Best For | Email, compatibility | Performance, modern apps | Standard algorithms, built-in |
When to Use Each Adapterโ
PGP/OpenPGP - Best for:
- Email encryption (PGP/MIME standard)
- Multi-recipient scenarios
- Compatibility with existing PGP infrastructure
- Long-term archival
NaCl/libsodium - Best for:
- High-performance applications
- Modern cryptography
- File encryption
- API token encryption
- Real-time data encryption
Node.js Crypto - Best for:
- Standard algorithms (AES, RSA)
- No external dependencies needed
- Password-based encryption (PBKDF2)
- Enterprise requirements (FIPS compliance)
Security Considerationsโ
Key Storageโ
โ DO NOT:
- Store private keys in plain text
- Commit keys to version control
- Log keys or passphrases
- Transmit keys over insecure channels
โ DO:
- Use environment variables for keys
- Encrypt private keys with strong passphrases
- Use hardware security modules (HSMs) for production
- Implement key rotation policies
- Use key derivation for password-based encryption
Best Practicesโ
-
Key Length:
- RSA: Minimum 2048 bits (4096 recommended)
- AES: 256 bits
- ECC: curve25519 or P-384
-
Algorithms:
- โ Prefer: AES-256-GCM, RSA-OAEP, ECDH, NaCl
- โ Avoid: DES, 3DES, MD5, SHA1
-
Key Derivation:
- PBKDF2: Minimum 100,000 iterations
- Use unique salts per encryption
- Consider Argon2 for new applications
-
Encrypted Data Integrity:
- Use authenticated encryption (GCM, Poly1305)
- Always verify signatures before trusting data
- Implement replay protection
Testingโ
Run the test suite:
npm test
Run tests for a specific adapter:
npm test -- test/unit/pgp.test.ts
npm test -- test/unit/nacl.test.ts
npm test -- test/unit/node.test.ts
Run file operations tests:
npm test -- test/unit/file-operations.test.ts
Performance Benchmarksโ
Approximate performance for 100KB data:
| Adapter | Encryption | Decryption | Key Generation |
|---|---|---|---|
| PGP (RSA 4096) | ~200ms | ~100ms | ~3000ms |
| NaCl (secretbox) | ~2ms | ~2ms | ~1ms |
| AES-256-GCM | ~5ms | ~5ms | N/A |
| RSA-OAEP 2048 | ~50ms | ~100ms | ~500ms |
Benchmarks run on M1 MacBook Pro. Your results may vary.
Documentationโ
- AGENT.md - Comprehensive developer guide with detailed API reference, architecture, and implementation phases
- API Types - TypeScript type definitions
- Error Handling - Custom error classes
Examplesโ
See the test directory for comprehensive examples:
- PGP Tests - Text, file, signature examples
- PGP Email Tests - Email encryption examples
- NaCl Tests - Symmetric and asymmetric examples
- Node Crypto Tests - AES, RSA, ECDSA examples
- File Operations Tests - File encryption for all adapters
Related Packagesโ
- @happyvertical/email - Email operations with encryption support
- @happyvertical/files - File operations
- @happyvertical/sql - Database operations (can encrypt fields)
Contributingโ
Contributions are welcome! Please see the root CONTRIBUTING.md for guidelines.
Developmentโ
# Install dependencies
pnpm install
# Run tests
npm test
# Run tests in watch mode
npm test -- --watch
# Build package
npm run build
# Lint and format
npm run lint
npm run format
Licenseโ
MIT License - see LICENSE for details.
Supportโ
- Issues: GitHub Issues
- Documentation: AGENT.md
- Examples: test/unit/
Built with โค๏ธ by HappyVertical