@voideddev/enc-server
v0.1.2
Published
Server-side encryption, hashing and obfuscation with map-based character substitution library
Maintainers
Readme
voideddev Enc-Server Library
A comprehensive server-side encryption and obfuscation library that provides a complete pipeline for securing sensitive data with compression, encryption, and character-level obfuscation.
🚀 Features
- Multi-layer Security: Compression → Encryption → Obfuscation pipeline
- Flexible Key Management: Support for custom keys, key rotation, and cloud-based key derivation
- Temperature-based Obfuscation: Configurable complexity levels (0.0 to 1.0)
- Multiple Compression Algorithms: Brotli, Gzip, or automatic selection
- AEAD Encryption: XChaCha20-Poly1305 (preferred) with AES-256-GCM fallback
- Deterministic Maps: Seeded random generation for reproducible obfuscation
- Comprehensive Statistics: Built-in metrics and performance tracking
- Hash Services: Complete hashing utilities for data integrity
📦 Installation
npm install @voideddev/enc-server🔧 Core Components
1. Encryption Module (encryption.ts)
Handles all cryptographic operations with AEAD (Authenticated Encryption with Associated Data).
import {
generateKey,
encrypt,
decrypt,
deriveKey,
} from "@voideddev/enc-server";
// Generate a random 256-bit key
const key = generateKey();
// Encrypt data
const encrypted = encrypt(dataBuffer, { key });
// Decrypt data
const decrypted = decrypt(encrypted, key);
// Derive key from API key + salt (for cloud mode)
// This creates a deterministic key from your API key and server salt
// Useful when you want the same key across server restarts without storing keys
const derivedKey = deriveKey(apiKey, serverSalt);
// Serialize/deserialize encryption results for storage
const serialized = serializeEncryptionResult(encrypted);
const deserialized = deserializeEncryptionResult(serialized);Key Functions:
generateKey(): Creates cryptographically secure 256-bit keysencrypt(data, options): Encrypts with AEAD only (XChaCha20-Poly1305 or AES-256-GCM) - NO compression or obfuscationdecrypt(result, key): Decrypts AEAD encrypted data (use withencrypt()) - NO decompression or deobfuscationderiveKey(apiKey, salt, info): HKDF-based key derivation for cloud deployments (creates deterministic keys from API key + salt)serializeEncryptionResult(result): Serialize encryption result for storagedeserializeEncryptionResult(serialized): Deserialize encryption result from storage
generateKey Response:
Buffer; // Returns a 32-byte (256-bit) random key as BufferderiveKey Response:
Buffer; // Returns a 32-byte (256-bit) deterministic key derived from API key + saltserializeEncryptionResult Response:
"base64_encoded_string"; // Returns serialized encryption result as base64 stringdeserializeEncryptionResult Response:
{
encrypted: Buffer, // Raw encrypted bytes
algorithm: "xchacha20-poly1305" | "aes-256-gcm", // Which algorithm was used
nonce: Buffer, // Random nonce/IV used
tag: Buffer // Authentication tag
}2. Compression Module (compression.ts)
Provides intelligent compression with automatic algorithm selection.
import {
compress,
decompress,
analyzeCompression,
} from "@voideddev/enc-server";
// Compress with automatic algorithm selection
const result = await compress(data, {
algorithm: "auto", // 'auto', 'brotli', 'gzip', 'none'
minSizeThreshold: 100, // Don't compress small data
compressionLevel: 6, // 1-9 for gzip, 1-11 for brotli
});
// Decompress
const decompressed = await decompress(result.compressed, result.algorithm);
// Analyze compression effectiveness
const analysis = await analyzeCompression(data);
console.log(`Recommendation: ${analysis.recommendation}`);
console.log(`Brotli ratio: ${analysis.brotliRatio}`);
console.log(`Gzip ratio: ${analysis.gzipRatio}`);analyzeCompression Response:
{
originalSize: 1000, // Original data size
gzipSize: 750, // Size after gzip compression
brotliSize: 680, // Size after brotli compression
gzipRatio: 0.75, // Gzip compression ratio
brotliRatio: 0.68, // Brotli compression ratio
recommendation: "brotli" // Recommended algorithm: 'gzip', 'brotli', or 'none'
}
**Features:**
- Automatic algorithm selection (Brotli preferred, Gzip fallback)
- Size-based compression decisions
- Compression ratio analysis
- Configurable thresholds and levels
### 3. Map Generator (`map-generator.ts`)
Creates temperature-based obfuscation maps for character substitution.
```typescript
import { generateMap, analyzeMap, TEMPERATURE_PROFILES } from '@voideddev/enc-server';
// Generate map with temperature control
const map = generateMap({
temperature: 0.5, // 0.0 (minimal) to 1.0 (extreme)
seed: 'my-seed', // For deterministic generation
charset: 'abcdef...' // Characters to obfuscate
});
// Analyze map characteristics
const analysis = analyzeMap(map);
console.log(`Temperature: ${analysis.temperature}`);
console.log(`Expansion ratio: ${analysis.expansionRatio}`);
console.log(`Compute score: ${analysis.computeScore}`);
console.log(`Total mappings: ${analysis.totalMappings}`);generateMap Response:
{
"a": ["x1y", "z2w", "m3n"], // Character 'a' maps to these strings
"b": ["p4q", "r5s"], // Character 'b' maps to these strings
"c": ["t6u", "v7w", "x8y", "z9a"] // Character 'c' maps to these strings
}analyzeMap Response:
{
temperature: 0.5, // Estimated temperature
totalMappings: 9, // Total number of mappings
averageMappingsPerChar: 3, // Average mappings per character
averageMappingLength: 3.2, // Average length of mappings
expansionRatio: 3.2, // Estimated expansion ratio
computeScore: 45, // Computational cost (0-100)
entropy: 0.85 // Entropy increase
}// Generate temperature comparison const comparison = generateTemperatureComparison('test-seed'); console.log('Available profiles:', Object.keys(comparison));
// Get temperature profile for specific temperature const profile = getTemperatureProfile(0.7); console.log('Profile:', profile);
// Calculate compute cost const cost = calculateComputeCost(map, dataLength); console.log('Compute cost:', cost);
// Get expansion ratio const ratio = getExpansionRatio(map); console.log('Expansion ratio:', ratio);
generateTemperatureComparison Response:
{
minimal: {
config: { temperature: 0.0, minMappings: 1, maxMappings: 2, /* ... */ },
map: { "a": ["x"], "b": ["y"] },
analysis: { temperature: 0.0, totalMappings: 2, /* ... */ }
},
low: {
config: { temperature: 0.2, minMappings: 1, maxMappings: 3, /* ... */ },
map: { "a": ["x", "y"], "b": ["z", "w"] },
analysis: { temperature: 0.2, totalMappings: 4, /* ... */ }
},
medium: {
config: { temperature: 0.5, minMappings: 2, maxMappings: 5, /* ... */ },
map: { "a": ["x1y", "z2w"], "b": ["m3n", "p4q"] },
analysis: { temperature: 0.5, totalMappings: 4, /* ... */ }
},
high: {
config: { temperature: 0.8, minMappings: 3, maxMappings: 8, /* ... */ },
map: { "a": ["x1y", "z2w", "m3n"], "b": ["p4q", "r5s", "t6u"] },
analysis: { temperature: 0.8, totalMappings: 6, /* ... */ }
},
extreme: {
config: { temperature: 1.0, minMappings: 5, maxMappings: 15, /* ... */ },
map: { "a": ["x1y", "z2w", "m3n", "p4q", "r5s"], "b": ["t6u", "v7w", "x8y", "z9a", "b1c"] },
analysis: { temperature: 1.0, totalMappings: 10, /* ... */ }
}
}getTemperatureProfile Response:
{
temperature: 0.7, // The temperature value
minMappings: 3, // Minimum mappings per character
maxMappings: 8, // Maximum mappings per character
minLength: 3, // Minimum mapping length
maxLength: 12, // Maximum mapping length
expansionRatio: 3.7, // Target expansion ratio
computeScore: 75 // Computational cost (0-100)
}calculateComputeCost Response:
45; // Returns computational cost as number (0-100)getExpansionRatio Response:
2.8; // Returns estimated expansion ratio as numbergenerateObfuscationMap Response:
{ "a": ["x1y", "z2w"], "b": ["m3n", "p4q"] } // Returns ObfuscationMap (deprecated, use generateMap instead)TEMPERATURE_PROFILES Constant:
{
minimal: {
temperature: 0.0,
minMappings: 1,
maxMappings: 2,
minLength: 1,
maxLength: 2,
expansionRatio: 1.1,
computeScore: 5
},
low: {
temperature: 0.2,
minMappings: 1,
maxMappings: 3,
minLength: 1,
maxLength: 4,
expansionRatio: 1.3,
computeScore: 15
},
medium: {
temperature: 0.5,
minMappings: 2,
maxMappings: 5,
minLength: 2,
maxLength: 8,
expansionRatio: 2.1,
computeScore: 40
},
high: {
temperature: 0.8,
minMappings: 3,
maxMappings: 8,
minLength: 3,
maxLength: 12,
expansionRatio: 3.7,
computeScore: 75
},
extreme: {
temperature: 1.0,
minMappings: 5,
maxMappings: 15,
minLength: 4,
maxLength: 20,
expansionRatio: 6.2,
computeScore: 100
}
}
**Temperature Profiles:**
- `minimal` (0.0): 1-2 mappings, short strings
- `low` (0.2): 1-3 mappings, short-medium strings
- `medium` (0.5): 2-5 mappings, medium strings
- `high` (0.8): 3-8 mappings, long strings
- `extreme` (1.0): 5-15 mappings, very long strings
### 4. Obfuscation Module (`obfuscation.ts`)
Performs character-level obfuscation using generated maps.
```typescript
import { obfuscate, deobfuscate, testObfuscationRoundTrip } from '@voideddev/enc-server';
// Obfuscate text
const result = obfuscate(text, map, {
seed: 'selection-seed',
selectionStrategy: 'random' // 'random', 'round-robin', 'shortest', 'longest'
});
// Deobfuscate text
const original = deobfuscate(result.obfuscated, map);
// Test round-trip integrity
const test = testObfuscationRoundTrip(text, map);
console.log(`Round-trip success: ${test.success}`);testObfuscationRoundTrip Response:
{
success: true, // Whether the round-trip was successful
originalText: "Hello World", // Original text
obfuscatedText: "obfuscated_version", // Obfuscated text
deobfuscatedText: "Hello World", // Text after deobfuscation
stats: {
originalLength: 11,
obfuscatedLength: 35,
expansionRatio: 3.18,
uniqueCharsObfuscated: 8,
mappingsUsed: 11
},
error: undefined // Error message if round-trip failed
}analyzeObfuscation Response:
{
coveragePercent: 85.5, // Percentage of characters that can be obfuscated
avgMappingsPerChar: 3.2, // Average mappings available per character
estimatedExpansionRatio: 2.8, // Estimated expansion ratio
entropyIncrease: 0.75, // Entropy increase from obfuscation
recommendedStrategy: "random" // Recommended selection strategy
}
**Selection Strategies:**
- `random`: Pseudo-random selection (default)
- `round-robin`: Cycle through mappings
- `shortest`: Choose shortest mapping
- `longest`: Choose longest mapping
### 5. Key Manager (`key-manager.ts`)
Manages encryption keys with rotation support. **Note: This is an in-memory key manager - keys are lost on restart unless you persist them.**
```typescript
import { KeyManager } from '@voideddev/enc-server';
// Create key manager with initial key
const km = new KeyManager(initialKey);
// Generate and activate new key
const newKey = km.generateAndActivateKey();
// Add external key
km.addKey(externalKey, true); // true = make active
// Get active key
const active = km.activeKey;
// Rotate to new key
const rotated = km.rotateKey();
// Get key by ID
const specificKey = km.getKey('key-id');
// Persist keys to survive restarts (you need to implement this)
const keysToPersist = km.toJSON();
// Store keysToPersist in your database/secure storage
**KeyManager Method Responses:**
**`generateAndActivateKey()` Response:**
```typescript
{
id: "a1b2c3d4", // Key ID
key: Buffer, // 32-byte encryption key
createdAt: Date // Creation timestamp
}addKey() Response:
{
id: "a1b2c3d4", // Key ID
key: Buffer, // 32-byte encryption key
createdAt: Date // Creation timestamp
}activeKey Getter Response:
{
id: "a1b2c3d4", // Active key ID
key: Buffer, // 32-byte encryption key
createdAt: Date // Creation timestamp
}getKey() Response:
{
id: "a1b2c3d4", // Key ID
key: Buffer, // 32-byte encryption key
createdAt: Date // Creation timestamp
}rotateKey() Response:
{
id: "e5f6g7h8", // New key ID
key: Buffer, // 32-byte encryption key
createdAt: Date // Creation timestamp
}toJSON() Response:
{
activeKeyId: "a1b2c3d4", // Currently active key ID
totalKeys: 3, // Total number of keys stored
createdAt: [
{ id: "a1b2c3d4", createdAt: Date },
{ id: "e5f6g7h8", createdAt: Date },
{ id: "i9j0k1l2", createdAt: Date }
] // Array of key creation timestamps
}6. Re-encryption (reencrypt.ts)
Handles key rotation workflows without exposing plaintext.
import { reEncryptWithNewKey } from "@voideddev/enc-server";
// Re-encrypt with new key
const reEncrypted = await reEncryptWithNewKey(
obfuscatedData,
map,
oldKey,
newKey,
{
regenerateMap: false, // Keep same map
temperature: 0.5, // New map temperature if regenerating
}
);reEncryptWithNewKey Response:
{
data: "newly_obfuscated_base64_string", // Re-encrypted obfuscated data
map: { "a": ["x1y", "z2w"], "b": ["m3n", "p4q"] }, // Obfuscation map (same or new)
originalSize: 13, // Original data size
compressedSize: 11, // Size after compression
obfuscatedSize: 45, // Final size after obfuscation
compressionRatio: 0.85, // How much compression helped
obfuscationStats: {
expansionRatio: 3.5, // How much obfuscation expanded the data
uniqueCharsObfuscated: 8, // Unique characters obfuscated
mappingsUsed: 12 // Number of mappings used
},
metadata: {
algorithm: "brotli", // Which compression was used
temperature: 0.5, // Obfuscation temperature used
outerCompression: "base64" // Additional compression info
}
}7. Statistics Tracker (stats.ts)
Collects and analyzes performance metrics.
import { StatsTracker } from '@voideddev/enc-server';
const stats = StatsTracker.instance;
// Add metrics
stats.add({
label: 'test-encryption',
originalSize: 1000,
compressedSize: 800,
obfuscatedSize: 1200,
expansionRatio: 1.2,
computeUnits: 50,
algorithm: 'brotli',
temperature: 0.5,
durationMs: 150
});
// Print summary
stats.printSummary();
// Export to JSON
stats.dumpToJson('encryption-stats.json');
**StatsTracker Method Responses:**
**`add()` Response:**
```typescript
undefined // Returns nothing, adds metric to internal collectionsummary Getter Response:
{
count: 150, // Total number of metrics
avgCompressionRatio: 0.75, // Average compression ratio
minCompressionRatio: 0.45, // Minimum compression ratio
maxCompressionRatio: 0.95, // Maximum compression ratio
avgExpansionRatio: 2.8, // Average expansion ratio
minExpansionRatio: 1.2, // Minimum expansion ratio
maxExpansionRatio: 4.5, // Maximum expansion ratio
totalBytesSaved: 25000, // Total bytes saved via compression
totalDataMoved: 150000, // Total data moved over wire
totalComputeUnits: 4500, // Total compute units used
totalDurationMs: 1200, // Total duration in milliseconds
avgStoredSize: 850, // Average stored size
maxStoredSize: 2500, // Maximum stored size
minStoredSize: 200 // Minimum stored size
}printSummary() Response:
undefined; // Prints formatted summary to console, returns nothingdumpToJson() Response:
undefined; // Writes JSON file to disk, returns nothing8. Hash Service (hash-service.ts)
Comprehensive hashing utilities for data integrity and verification.
import { hashService } from "@voideddev/enc-server";
// Basic hashing
const hash = await hashService.generateHash(data, "sha256");
// Salted hashing (for any data)
const saltedHash = await hashService.generateHashWithSalt(data, salt);
const isValid = await hashService.verifyWithSalt(
data,
saltedHash,
salt,
"sha256"
);
// High iteration hashing (for any sensitive data)
const { hash, salt } = await hashService.hashWithHighIterations(data);
const isValid = await hashService.verifyWithHighIterations(data, hash, salt);
// HMAC (Hash-based Message Authentication Code) for data integrity
// HMAC provides both authenticity and integrity - different from regular hashing
const hmac = await hashService.generateHMAC(data, secretKey);
const isValid = await hashService.verifyHMAC(data, hmac, secretKey);
// Safety numbers (like Signal) for key verification
// Converts hash to human-readable number groups for manual verification
const safetyNumbers = await hashService.generateSafetyNumbers(data);Hash Service Response Examples:
generateHash Response:
"a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"; // SHA-256 hash stringgenerateHashWithSalt Response:
"a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"; // Salted hash stringhashWithHighIterations Response:
{
hash: "$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewdBPj4J/HS.iQe", // bcrypt hash
salt: "random_salt_string" // Salt used
}generateHMAC Response:
"hmac_hash_string_for_data_integrity"; // HMAC hash stringgenerateSafetyNumbers Response:
"12345 67890 12345 67890"; // Human-readable number groupsgenerateRandomHash Response:
"a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"; // Random hash stringgenerateFingerprint Response:
"a665a459"; // Hash fingerprint of specified lengthgenerateRandomSalt Response:
"random_salt_string"; // Random salt stringgenerateRandomKey Response:
"random_key_string"; // Random key string for HMACsecureWipe Response:
undefined; // Returns nothing, securely wipes the buffergenerateFileHash Response:
"file_hash_string"; // Hash of the file contentsgenerateStreamHash Response:
"stream_hash_string"; // Hash of the stream datacompareHash Response:
true; // Returns boolean for hash comparisonVerification Functions Response:
true; // Returns boolean for all verify functions🎯 Usage Patterns
Understanding the Different Flows
The library provides three main approaches:
- Full Pipeline (
encryptWithMap/decryptWithMap): Complete security with compression → encryption → obfuscation - Individual Components: Use each step separately (compress, encrypt, obfuscate)
- Obfuscation Only: Just character substitution without encryption
Important: The encrypt() and decrypt() functions are NOT full pipeline - they only do AEAD encryption/decryption. They don't handle compression or obfuscation.
1. Full Pipeline (Recommended)
import {
encryptWithMap,
decryptWithMap,
generateKey,
} from "@voideddev/enc-server";
// Generate key
const key = generateKey();
// Full pipeline: compress → encrypt → obfuscate
const result = await encryptWithMap("sensitive data", {
key,
obfuscationOptions: {
temperature: 0.5,
seed: "my-seed",
},
compressionOptions: {
algorithm: "auto",
},
});
// Full pipeline: deobfuscate → decrypt → decompress
const decrypted = await decryptWithMap(
result.data,
result.map,
key,
result.metadata.algorithm
);encryptWithMap Response:
{
data: "obfuscated_base64_string", // Final obfuscated result
map: { "a": ["x1y", "z2w"], "b": ["m3n", "p4q"] }, // Obfuscation map
originalSize: 13, // Original data size
compressedSize: 11, // Size after compression
obfuscatedSize: 45, // Final size after obfuscation
compressionRatio: 0.85, // How much compression helped
obfuscationStats: {
expansionRatio: 3.5, // How much obfuscation expanded the data
uniqueCharsObfuscated: 8, // Unique characters obfuscated
mappingsUsed: 12 // Number of mappings used
},
metadata: {
algorithm: "brotli", // Which compression was used
temperature: 0.5, // Obfuscation temperature used
outerCompression: "base64" // Additional compression info
}
}decryptWithMap Response:
"sensitive data"; // Returns the original string directly2. Service-based Usage (Full Pipeline)
import { VoidedService } from "@voideddev/enc-server";
// Self-hosted mode
const service = new VoidedService({
mode: "self-hosted",
temperature: 0.5,
seed: "my-seed",
});
// Cloud mode (uses deriveKey internally)
const cloudService = new VoidedService({
mode: "cloud",
apiKey: "your-api-key",
serverSalt: "your-server-salt",
temperature: 0.3,
});
// Encrypt (full pipeline: compress → encrypt → obfuscate)
const result = await service.encrypt("sensitive data");
// Decrypt (full pipeline: deobfuscate → decrypt → decompress)
const decrypted = await service.decrypt(result.data, result.map);3. Individual Components (Step by Step)
import {
compress,
encrypt,
obfuscate,
decompress,
decrypt,
deobfuscate,
} from "@voideddev/enc-server";
// Step 1: Compress
const compressed = await compress(data, { algorithm: "brotli" });
// Step 2: Encrypt (use decrypt() to reverse this)
const encrypted = encrypt(compressed.compressed, { key });
// Step 3: Obfuscate
const obfuscated = obfuscate(JSON.stringify(encrypted), map);
// To decrypt, reverse the process:
// Step 1: Deobfuscate
const deobfuscated = deobfuscate(obfuscated, map);
// Step 2: Decrypt (use decrypt(), not decryptWithMap())
const decrypted = decrypt(JSON.parse(deobfuscated), key);
// Step 3: Decompress
const final = await decompress(decrypted, "brotli");compress Response:
{
compressed: Buffer, // Compressed data
algorithm: "brotli", // Which algorithm was used
originalSize: 1000, // Original size
compressedSize: 750, // Size after compression
compressionRatio: 0.75 // Ratio (compressed/original)
}encrypt Response:
{
encrypted: Buffer, // Raw encrypted bytes
algorithm: "aes-256-gcm", // Which algorithm was used
nonce: Buffer, // Random nonce/IV used
tag: Buffer // Authentication tag
}obfuscate Response:
{
obfuscated: "obfuscated_text_string", // Obfuscated text
map: { "a": ["x1y", "z2w"] }, // The map used for obfuscation
stats: {
originalLength: 100, // Original text length
obfuscatedLength: 350, // Length after obfuscation
expansionRatio: 3.5, // How much it expanded
uniqueCharsObfuscated: 15, // Unique chars obfuscated
mappingsUsed: 25 // Number of mappings used
}
}decrypt Response:
Buffer; // Returns the original decrypted data as Bufferdeobfuscate Response:
"original_text"; // Returns the original text stringdecompress Response:
Buffer; // Returns the original decompressed data as Buffer4. Key Rotation Workflow
5. Key Rotation Workflow
import { KeyManager, reEncryptWithNewKey } from "@voideddev/enc-server";
const km = new KeyManager();
km.generateAndActivateKey();
// Encrypt with current key
const encrypted = await encryptWithMap(data, { key: km.activeKey.key });
// Rotate key
const newKey = km.rotateKey();
// Re-encrypt with new key
const reEncrypted = await reEncryptWithNewKey(
encrypted.data,
encrypted.map,
km.getKey(encrypted.keyId).key,
newKey.key
);6. Obfuscation Only (No Encryption)
import { VoidedService } from "@voideddev/enc-server";
const service = new VoidedService();
// Obfuscate without encryption (just character substitution)
const { obfuscated, map } = service.obfuscateOnly("sensitive text", {
temperature: 0.7,
});
// Deobfuscate
const original = service.deobfuscateOnly(obfuscated, map);obfuscateOnly Response:
{
obfuscated: "obfuscated_text_string", // Obfuscated text
map: { "a": ["x1y", "z2w"], "b": ["m3n", "p4q"] } // Obfuscation map
}deobfuscateOnly Response:
"sensitive text"; // Returns the original string directly7. Advanced Configuration
import { encryptWithMap, generateMap } from "@voideddev/enc-server";
// Custom temperature configuration
const map = generateMap({
temperature: 0.8,
seed: "deterministic-seed",
customTemperatureConfig: {
minMappings: 5,
maxMappings: 12,
minLength: 4,
maxLength: 15,
},
});
// Advanced encryption options
const result = await encryptWithMap(data, {
key,
mapKey: "reusable-map-key",
obfuscationOptions: {
temperature: 0.6,
seed: "selection-seed",
selectionStrategy: "round-robin",
maxTemperatureForSmallData: 0.3,
},
compressionOptions: {
algorithm: "brotli",
level: 11,
threshold: 200,
},
});🔒 Security Considerations
Key Management
- Never hardcode keys in your application
- Use environment variables or secure key stores
- Implement proper key rotation policies
- Consider using cloud KMS services for production
- KeyManager is in-memory only - implement persistence for production use
- deriveKey() creates deterministic keys from API key + salt (useful for cloud deployments)
Hashing vs Encryption vs HMAC
- Hashing: One-way transformation (SHA-256, SHA-512) - cannot be reversed
- Encryption: Two-way transformation (AES, XChaCha20) - can be decrypted with key
- HMAC: Hash-based Message Authentication Code - provides integrity + authenticity
- High Iteration Hashing: Slow, salted hashing (bcrypt, PBKDF2) - for any sensitive data
Temperature Settings
- Lower temperatures (0.0-0.3): Better performance, less obfuscation
- Medium temperatures (0.4-0.6): Balanced performance and security
- Higher temperatures (0.7-1.0): Maximum obfuscation, higher computational cost
Compression Security
- Compression can leak information about data patterns
- Consider using
algorithm: 'none'for highly sensitive data - Monitor compression ratios for potential information leakage
Map Security
- Maps should be treated as sensitive data
- Store maps securely alongside encrypted data
- Consider regenerating maps periodically
- Use deterministic seeds for reproducible obfuscation
📊 Performance Guidelines
Size Thresholds & Limits
- Small data (< 100 bytes): Skip compression
- Medium data (100-1KB): Use lower temperatures (0.0-0.3)
- Large data (> 1KB): Full pipeline with auto-compression
Server-side hard limit: operations are validated against a maximum item size of 1 TiB. If exceeded, an error with code VOI_SERVER_FILE_TOO_LARGE is thrown.
Memory Usage
- High temperatures increase memory usage
- Monitor expansion ratios for large datasets
- Consider streaming for very large files
Computational Cost
- Temperature directly affects compute cost
- Use
calculateComputeCost()to estimate requirements - Monitor
StatsTrackerfor performance metrics
🧪 Testing and Validation
import {
testObfuscationRoundTrip,
analyzeObfuscation,
} from "@voideddev/enc-server";
// Test obfuscation integrity
const test = testObfuscationRoundTrip(text, map);
if (!test.success) {
console.error("Obfuscation test failed:", test.error);
}
// Analyze obfuscation effectiveness
const analysis = analyzeObfuscation(text, map);
console.log(`Coverage: ${analysis.coveragePercent}%`);
console.log(`Recommended strategy: ${analysis.recommendedStrategy}`);🔧 Integration Examples
Express.js Middleware
import { VoidedService } from "@voideddev/enc-server";
const voidedService = new VoidedService({
mode: "cloud",
apiKey: process.env.VOIDED_API_KEY,
serverSalt: process.env.VOIDED_SERVER_SALT,
});
app.post("/encrypt", async (req, res) => {
try {
const result = await voidedService.encrypt(req.body.data);
res.json({
encrypted: result.data,
map: result.map,
metadata: result.metadata,
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});Database Integration
import { VoidedService } from "@voideddev/enc-server";
const service = new VoidedService();
// Encrypt before storing
const sensitiveData = await service.encrypt(userData);
await db.users.create({
id: userId,
encryptedData: sensitiveData.data,
obfuscationMap: JSON.stringify(sensitiveData.map),
algorithm: sensitiveData.metadata.algorithm,
});
// Decrypt when retrieving
const user = await db.users.findById(userId);
const decryptedData = await service.decrypt(
user.encryptedData,
JSON.parse(user.obfuscationMap),
user.algorithm
);📈 Monitoring and Metrics
import { StatsTracker } from "@voideddev/enc-server";
// Add metrics to your encryption operations
const stats = StatsTracker.instance;
const startTime = Date.now();
const result = await encryptWithMap(data, options);
const duration = Date.now() - startTime;
stats.add({
label: "user-data-encryption",
originalSize: data.length,
compressedSize: result.compressedSize,
obfuscatedSize: result.obfuscatedSize,
expansionRatio: result.obfuscationStats.expansionRatio,
computeUnits: calculateComputeCost(result.map, data.length),
algorithm: result.metadata.algorithm,
temperature: result.metadata.temperature,
durationMs: duration,
});
// Generate reports
stats.printSummary();🚨 Error Handling
import { encryptWithMap, decryptWithMap } from "@voideddev/enc-server";
try {
const result = await encryptWithMap(data, { key });
// Handle success
} catch (error) {
if (error.message.includes("Encryption key is required")) {
// Handle missing key
} else if (error.message.includes("Compression failed")) {
// Handle compression error
} else {
// Handle other errors
}
}
try {
const decrypted = await decryptWithMap(encryptedData, map, key);
// Handle success
} catch (error) {
if (error.message.includes("Decryption failed")) {
// Handle decryption error (wrong key, corrupted data)
} else if (error.message.includes("Decompression failed")) {
// Handle decompression error
}
}📚 API Reference
Main Functions
Full Pipeline Functions:
encryptWithMap(data, options): Full pipeline: compress → encrypt → obfuscatedecryptWithMap(encryptedData, map, key, algorithm): Full pipeline: deobfuscate → decrypt → decompressencryptWithMapBatch([{ data, options, id? }]): Batch full-pipeline encryptdecryptWithMapBatch([{ obfuscatedData, map, key, algorithm?, id? }]): Batch full-pipeline decryptencryptWithMapAuto(input: string | Buffer | Readable, options): Stream-oriented convenience. If input is large or a stream, emits NDJSON chunk records; otherwise emits a single chunk record.decryptWithMapAuto(input: string | Buffer | Readable, map, key, algorithm): Stream-oriented convenience. Accepts NDJSON chunk records and outputs plaintext bytes.encryptWithMapStream(input: Readable, options, chunkSize?): Streamed full pipeline (NDJSON per chunk)decryptWithMapStream(input: Readable, map, key, algorithm?): Streamed full pipeline (plaintext out)
Individual Components:
encrypt(data, options): Encrypt with AEAD only (no compression/obfuscation)decrypt(result, key): Decrypt AEAD data only (no deobfuscation/decompression) - use this withencrypt()generateKey(): Generate random 256-bit keyderiveKey(apiKey, salt, info): Derive deterministic key using HKDF from API key + saltserializeEncryptionResult(result): Serialize encryption result to stringdeserializeEncryptionResult(serialized): Deserialize encryption result from stringgenerateMap(options): Create obfuscation mapobfuscate(text, map, options): Obfuscate text (no encryption)deobfuscate(obfuscatedText, map): Deobfuscate text (no decryption)testObfuscationRoundTrip(text, map, options): Test obfuscation integrityanalyzeObfuscation(text, map): Analyze obfuscation effectivenesscompress(data, options): Compress datadecompress(compressedData, algorithm): Decompress dataanalyzeCompression(data): Analyze compression effectivenessreEncryptWithNewKey(obfuscatedData, map, oldKey, newKey, opts): Re-encrypt with new keycalculateComputeCost(map, dataLength): Calculate computational costgetExpansionRatio(map): Get expansion ratio estimateanalyzeMap(map): Analyze map characteristicsgetTemperatureProfile(temperature): Get temperature configurationgenerateTemperatureComparison(seed): Generate temperature comparison mapsgenerateObfuscationMap(seed): Legacy function for backward compatibility (deprecated, use generateMap instead)
Classes
- Streaming primitives (for very large inputs):
createCompressionStream,createDecompressionStreamcreateEncryptionStream,createDecryptionStreamcreateObfuscateStream,createDeobfuscateStream
When to stream
If payload ≥ 1 GiB or you already have a Node stream: use
encryptWithMapAuto/decryptWithMapAutoor the streaming primitives.If you call the non-streaming single-call APIs with very large payloads, the functions throw
VOI_STREAMING_REQUIREDand suggest the streaming alternative.VoidedService: Main service class for easy integration (handles key management internally)KeyManager: In-memory key management with rotation support (keys lost on restart)StatsTracker: Performance metrics collectionHashService: Comprehensive hashing utilities (includes HMAC, high iteration hashing, safety numbers)
HashService Methods
generateHash(data, algorithm): Generate hash using specified algorithmgenerateHashWithSalt(data, salt, algorithm): Generate salted hashcompareHash(data, hash, algorithm): Compare hash with timing-safe comparisonhashWithHighIterations(data, salt): Hash data with high iteration countverifyWithHighIterations(data, hash, salt): Verify high iteration hashverifyWithSalt(data, hash, salt, algorithm): Verify salted hashgenerateRandomHash(algorithm): Generate random hashgenerateFingerprint(data, length): Generate hash fingerprintgenerateSafetyNumbers(data, groupSize): Generate safety numbers for key verificationgenerateHMAC(data, key, algorithm): Generate HMAC for data integrityverifyHMAC(data, hmac, key, algorithm): Verify HMACgenerateRandomSalt(length): Generate random saltgenerateRandomKey(length): Generate random key for HMACsecureWipe(buffer): Securely wipe sensitive data from memorygenerateFileHash(filePath, algorithm): Generate hash for file integritygenerateStreamHash(stream, algorithm): Generate hash for stream data
Constants
TEMPERATURE_PROFILES: Pre-defined temperature configurations
Interfaces
EncryptWithMapOptions: Configuration for encryptionEncryptWithMapResult: Result from encryptionVoidedServiceOptions: Service configuration optionsObfuscationMap: Character substitution mappingsTemperatureConfig: Obfuscation complexity settingsGenerateMapOptions: Map generation optionsCompressionOptions: Compression configurationCompressionResult: Compression operation resultEncryptionOptions: Encryption configurationEncryptionResult: Encryption operation resultObfuscationResult: Obfuscation operation resultStoredKey: Key storage interfaceMetric: Performance metric interface
🤝 Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
📄 License
MIT License - see LICENSE file for details.
🆘 Support
For issues, questions, or contributions, please open an issue on the GitHub repository.
