Back to Blog
Designing Secure File Storage with AES-256 & RSA in Spring Boot

Designing Secure File Storage with AES-256 & RSA in Spring Boot

Parth Shah

Why Two Keys Are Better Than One

Encrypting user files is easy—until you need zero-trust sharing, seamless node fail-over, and 99.9 % uptime. EnLock solves this with a dual-layer pipeline:

  • AES-256 (GCM) — fast, symmetric encryption for the file bytes
  • RSA-2048 — wraps the AES key so only the owner (or a delegated reader) can decrypt it

TL;DR: Data moves fast under AES, keys stay safe under RSA.


1 | System at 10,000 ft

System Architecture at 10,000 ft

The AES session key never leaves Crypto Service unencrypted; RSA-wrapped blobs live in KeyVault under versioned mounts.


2 | Spring Boot Crypto Service — Core Snippet

// CryptoService.java
public EncryptedBlob encrypt(MultipartFile file, UUID ownerId) throws Exception {
  byte[] aesKey = SecureRandom.getInstanceStrong().generateSeed(32);      // 256-bit
  Cipher aes = Cipher.getInstance("AES/GCM/NoPadding");
  aes.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(aesKey, "AES"));

  byte[] cipherBytes = aes.doFinal(file.getBytes());
  byte[] iv          = aes.getIV();

  byte[] wrappedKey  = rsaWrap(aesKey, ownerPublicKey(ownerId));

  return new EncryptedBlob(cipherBytes, wrappedKey, iv);
}

Performance tip: Use a per-thread CipherPool to avoid JVM re-init overhead under high upload concurrency.


3 | Node Failure ≠ Data Loss

Distributed nodes register with Apache ZooKeeper:

  1. Ephemeral znode per worker /workers/{nodeId}
  2. Upload API picks the least-loaded node via watcher callbacks
  3. On node death, ZooKeeper triggers a replication rebalance job

The encrypted file is sharded n=3 across peers, each storing only AES-ciphertext—never the key.


4 | Threat Model & Counter-Measures

ThreatMitigation
S3 bucket leakData still AES-GCM; attacker lacks key.
KeyVault compromiseKeys RSA-wrapped per user; attacker also needs user’s private key.
Replay or tamperGCM tag validation → AEADBadTagException aborts read.
Privilege escalationJWT carries scope=files:{UUID}; Spring Security enforces row-level ACL.
Brute-forcePBKDF2-HMAC-SHA512 on user passphrases; 310 000 iterations (OWASP 2025).

5 | Performance vs. Security Trade-offs

ConfigUpload 10 MBDownload 10 MBNotes
AES-GCM 256 bit140 ms120 msHW AES-NI on Xeon
AES-CBC + HMAC210 ms185 msTwo-pass I/O
RSA onlyToo slow, block-size limited

Bottom line: AES-GCM with AES-NI gives near-disk throughput while preserving integrity via GCM tag.


6 | Rotating Keys Without Downtime

  1. Mark key-rotation flag per user
  2. Background job decrypts with old RSA key, re-wraps AES key with new RSA key
  3. Update key_version column; readers fetch latest automatically
  4. Once 100 %, revoke old RSA key in KeyVault (soft-delete -> purge after TTL)

This hot rotation completes ~1 TB/hour on a 4-core node with negligible user impact (< 5 ms extra latency).


7 | Compliance Checklist

StandardControl Implemented
ISO 27001 A.10.1AES-256 encryption at rest & in transit
GDPR Art. 32Pseudonymisation via per-file UUID, strong crypto
PCI-DSS v4.0AES-256 for cardholder scans, RSA key storage in HSM
SOC 2 CC6Logical access via RBAC, audit logs immutable (S3 Object Lock)

8 | Observability

  • Prometheus – custom crypto_op_latency_ms, keyvault_calls_total
  • Grafana – heat-map shows if encrypt | decrypt outliers exceed SLA 150 ms
  • AlertManager – triggers if GCM tag failures > 0.01 % of ops

Field Results

MetricPre-crypto prototypeEnLock prod
SLA breaches (>150 ms)2.8 %0.4 %
Pen-test critical findings50
Data-recovery drillsN/A100 % success across 3 node wipeouts

Key Takeaways

  • Layered crypto beats single-key setups—compromise one layer, data stays safe.
  • ZooKeeper + sharding keeps uploads available even when a node disappears.
  • Hot key rotation is possible if you separate data & key stores and version aggressively.
  • Invest in observability early; crypto bugs hide in latency tails.

Security isn’t a feature toggle—it’s architecture. Build it in from day one, and your future self (and auditors) will thank you.

SecurityJavaSpring Boot