DEV Community

How we implemented client-side encrypted streaming in Flutter with Dart Isolates

Over the past few months, we built and launched RonikCloud (https://ronikcloud.com/), a client-side encrypted cloud storage app built in Flutter across Web, Desktop (macOS, Windows, Linux), and Mobile (iOS, Android). In this article, we share our architectural choices, lessons learned, and how we solved client-side encrypted streaming performance in Flutter. The Problem: Cryptography vs 60/120 FPS UI Client-side encryption requires running heavy authenticated cryptographic operations (AES-GCM-256 / XChaCha20-Poly1305 ) over multi-gigabyte files. If executed on the main Dart UI thread, streaming encryption causes UI jank, frame drops, and frozen progress indicators. Key Architecture Components 1. Offloading Cryptography to Background Isolates Using Dart's package:cryptography , we stream chunks of data through dedicated background worker isolates. - Files are read in memory-bounded chunks (5MB-16MB). - Each chunk is transformed and encrypted with authenticated tags inside an isolate. - Encrypted payloads are directly streamed into S3 pre-signed upload channels. - This keeps the UI buttery smooth at 60fps/120fps even during heavy multi-gigabyte transfers. 2. Envelope & Path Encryption (Zero Knowledge of Names) - File Payload: Encrypted locally before upload. - File & Folder Names: Encrypted client-side. The backend stores only opaque randomized object identifiers, rejecting plaintext filenames and local folder structures. - Separate Envelopes: New file contents and protected names use separate authenticated encryption envelopes. 3. Zero-Knowledge Web Fragments For browser-based file exchange and encrypted file requests: - Cryptographic keys are embedded exclusively in the URL hash fragment ( #key=... ). - Because web browsers never send the hash fragment to web servers or proxies, our backend API never receives the shared key. - The web client extracts the fragment directly in browser memory and decrypts the streaming bytes locally. 4. Cross-Platform Sync Engine - Desktop platforms (macOS, Windows, Linux) utilize local filesystem event watchers with automatic conflict resolution. - Mobile platforms (iOS, Android) adapt to OS background execution limits with resumable upload chunking. Metadata & Boundary Disclosures Transparency is crucial in cryptographic software. Here is our honest metadata boundary disclosure: - Client-Side Encrypted: File payloads, file/folder names, request secrets. - Visible to Infrastructure: Account relationships, subscription tier, ciphertext object sizes, upload/modification timestamps, and IP network traffic. - Audit Status: RonikCloud is currently in an open founding beta and has not yet undergone an independent third-party audit. Questions for the Community: - What evidence or verifications do you look for before trying a new client-side encrypted storage tool? - What are your favorite patterns for managing memory-efficient streaming pipelines in Flutter / Dart? We'd love to hear your thoughts and feedback! Top comments (0)

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.