Zero-Knowledge Envelope Encryption
AES-256-GCM authenticated cipher, ephemeral per-object DEKs, EF Core converters, and timing-attack prevention.
Aarkam implements a strict Zero-Knowledge Envelope Encryption architecture. All data ingested into the storage fabric is encrypted client-side at the gateway layer before any chunk touches internal network switches or physical disks.
1. Two-Tier Envelope Encryption Hierarchy
Aarkam decouples data encryption into a two-tier key hierarchy:
- Key Encrypting Key (KEK): The master key, hosted exclusively inside customer-operated Hardware Security Modules (HSMs) or enterprise KMS (e.g., Thales CipherTrust, Entrust nShield, AWS KMS, HashiCorp Vault). KEKs never leave the secure hardware boundary.
- Data Encryption Key (DEK): An ephemeral, cryptographically random 256-bit key generated uniquely for each uploaded object. The DEK is encrypted with the KEK and stored in object metadata.
2. Cryptographic Implementation Details
AES-256-GCM Authenticated Encryption
All object chunks are encrypted using AES-256-GCM (Galois/Counter Mode), providing confidentiality, forward secrecy, and built-in cryptographic authentication via a 128-bit authentication tag:
- Key Size: 256 bits (32 bytes)
- Nonce/IV: 96 bits (12 bytes), generated via
RandomNumberGenerator - Authentication Tag: 128 bits (16 bytes), verifying ciphertext integrity against tampering
Transparent Entity-Level Database Encryption
Internal metadata and tenant registries stored in the relational database (PostgreSQL / EF Core) or embedded Kdouja LSM tables are transparently encrypted at the entity level via custom EF Core EncryptionConverter attributes and AES-256-GCM, guaranteeing zero plaintext credentials even during raw database file inspection.
3. Side-Channel Timing Attack Prevention
In high-assurance security environments, variable-time string comparisons allow attackers to infer cryptographic secrets through timing discrepancies. Aarkam mitigates this across all authentication paths (such as Node Agent API keys and HMAC signatures) using constant-time verification:
// Verification in NodeAgentController.cs preventing side-channel attacks
if (!CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(providedApiKey),
Encoding.UTF8.GetBytes(expectedApiKey)))
{
return Unauthorized();
}