A AEGISCRYPTDOCS
Launch app ↗

ZERO-KNOWLEDGE FILE ENCRYPTION

AEGIS
DOCS.

Everything you need to run, understand, and deploy AegisCrypt — a browser-only AES-256-GCM vault that never uploads your files.

  • NO SERVER
  • NO UPLOADS
  • NO TELEMETRY
v2 FILE FORMAT
aegiscrypt — bash
$ git clone https://github.com/Bangkahdev/AegisCrypt-Web.git
$ cd AegisCrypt-Web
$ npm install
$ npm start

  VITE v8 ready
  Local:   http://localhost:5173/
  Uploads: 0 files
  Status:  all crypto runs locally
AES-256GCM
100KPBKDF2
1 MBCHUNKS
01

Overview

AegisCrypt is a client-side encryption suite that seals files into .aegis containers using the Web Crypto API. Passwords, key material, and plaintext stay inside browser memory.

CIPHER

AES-256-GCM

Authenticated encryption detects tampering immediately. A single changed bit makes decryption fail instead of emitting garbage.

KDF

PBKDF2 100K

HMAC-SHA-256 with 100,000 iterations and a fresh 32-byte salt per file. Built to slow down brute-force and rainbow-table attacks.

2FA

Keyfile

Combine a password with any file. Key material becomes password + SHA-256(keyfile), so the exact file is required to decrypt.

STREAM

1 MB chunks

Encryption streams files in 1 MB blocks, each with its own IV, so multi-gigabyte files do not need one giant heap allocation.

LOCAL

Zero uploads

There is no backend. The app is a static bundle; every cryptographic operation runs in your browser tab.

INTEGRITY

Tamper detection

GCM authentication tags and strict chunk-length validation reject corrupted or modified containers.

What "zero-knowledge" means here

AegisCrypt does not operate a server that could see your data. The browser performs key derivation and encryption locally, and the resulting .aegis file is downloaded directly to your device.

02

Quickstart

Prerequisites

Node.js 18 or newer, npm, and a modern browser with the Web Crypto API (Chrome, Edge, Firefox, or Safari).

terminal
# 1. Clone the repository
git clone https://github.com/Bangkahdev/AegisCrypt-Web.git

# 2. Enter the project
cd AegisCrypt-Web

# 3. Install dependencies
npm install

# 4. Start the dev server
npm start

The app opens at http://localhost:5173. For a production build and a local preview:

build & test
npm run build        # typecheck + production bundle
npm run preview      # serve the production build
npm run test:unit    # Vitest security suite
npm run test:e2e     # Playwright browser tests
ScriptWhat it does
npm startVite dev server with HMR
npm run buildTypeScript check, then Vite production build
npm run test:unitRuns the Vitest crypto suite once
npm run test:e2eRuns Playwright end-to-end browser tests
03

Architecture

Every operation follows the same pipeline. Nothing is sent over the network, and every chunk gets its own initialization vector.

INPUT Password + Keyfile
→
KDF PBKDF2-SHA256
→
CIPHER AES-256-GCM
→
OUTPUT .aegis container
STEP 1

Key material

The password bytes are combined with the SHA-256 hash of the optional keyfile. This keeps mixed input sizes consistent and makes the keyfile part of the derived key.

STEP 2

Key derivation

PBKDF2-HMAC-SHA-256 runs 100,000 iterations over a fresh 32-byte random salt, producing a 256-bit AES key.

STEP 3

Encryption

Each 1 MB plaintext chunk is encrypted with AES-256-GCM and a unique 12-byte IV. The IV and ciphertext are packed with a 4-byte length.

STEP 4

Container

The header plus encrypted chunks are assembled as a Blob and downloaded as filename.ext.aegis.

There is no recovery path

If you lose the password or the exact keyfile, the data cannot be decrypted. AegisCrypt has no server, reset flow, or backdoor.

04

Usage

ENCRYPT

Seal a file

  1. Enter a strong master password.
  2. Optionally enable the keyfile and select a file.
  3. Click Start Session.
  4. Drop files or folders into the queue.
  5. Click Encrypt and accept the download.
DECRYPT

Restore a file

  1. Use the exact password and keyfile from encryption.
  2. Drop the .aegis file into the queue.
  3. Click Decrypt.
  4. The original file is downloaded automatically.
Folder support

The drop zone accepts multiple files at once, including files selected from a folder picker. Every file is processed sequentially and logged in the operation console.

05

File format

The .aegis v2 container is a simple binary format: a fixed 38-byte header followed by length-prefixed chunks.

Header

OffsetSizeFieldValue
05MagicASCII AEGIS
51Version0x02
632SaltCSPRNG, per file

Chunk record (repeated)

SizeFieldNotes
4LengthLittle-endian; IV + ciphertext + tag
12IVFresh CSPRNG value for every chunk
nCiphertextAES-256-GCM output
16Auth tagAppended by Web Crypto
Compatibility

Version 2 containers are interoperable with the desktop version. A different version byte is rejected instead of being processed with the wrong layout.

06

API reference

The crypto engine lives in src/services/cryptoService.ts and is fully browser-based.

ExportSignaturePurpose
processFileEncrypt (file, password, keyFileBuffer, signal, onProgress) => Promise<Blob> Streams a file into a sealed container
processFileDecrypt (fileBuffer, password, keyFileBuffer, signal, onProgress) => Promise<Blob> Validates the header and restores the original
downloadBlob (data, filename) => void Triggers a browser download
getEncryptedFilename (name) => string Appends .aegis
getDecryptedFilename (name) => string Removes .aegis or adds a prefix
prepareKeyMaterial (password, keyFileBuffer) => Promise<Uint8Array> Combines password and keyfile hash
deriveKey (material, salt, usage) => Promise<CryptoKey> PBKDF2 key derivation
example.ts
import {
  processFileEncrypt,
  processFileDecrypt,
  downloadBlob,
} from "./services/cryptoService";

const controller = new AbortController();

const sealed = await processFileEncrypt(
  file,
  password,
  keyFileBuffer,
  controller.signal,
  (bytes) => console.log(`${bytes} bytes processed`)
);

downloadBlob(sealed, `${file.name}.aegis`);

const restored = await processFileDecrypt(
  await sealed.arrayBuffer(),
  password,
  keyFileBuffer,
  controller.signal,
  () => {}
);

downloadBlob(restored, file.name);

Constants

ConstantValueMeaning
PBKDF2_ITERATIONS100,000Key stretching rounds
SALT_LENGTH32 bytesPer-file random salt
IV_LENGTH12 bytesGCM initialization vector
TAG_LENGTH_BITS128GCM authentication tag
KEY_LENGTH256AES key size
CHUNK_SIZE1 MiBStreaming block size
07

Project structure

repository
AegisCrypt-Web/
├── public/
│   └── favicon.svg
├── src/
│   ├── components/
│   │   ├── ui/                 # shadcn-style primitives
│   │   ├── FileList.tsx        # queue UI
│   │   ├── LogBox.tsx          # operation log
│   │   ├── LoginScreen.tsx     # session entry
│   │   └── PasswordInput.tsx   # strength meter
│   ├── lib/
│   │   └── utils.ts            # cn() helper
│   ├── services/
│   │   └── cryptoService.ts    # AES-GCM engine
│   ├── App.tsx                 # orchestration
│   ├── constants.ts            # crypto + format constants
│   ├── index.css               # theme tokens
│   ├── main.tsx                # entry point
│   └── types.ts                # shared interfaces
├── docs-site/                  # this neo-brutalist docs site
├── tests/
│   ├── cryptoService.test.ts
│   └── e2e/app.spec.ts
├── cloudflare.config.ts        # Workers deployment
└── vite.config.ts
08

Security

PROTECTS

What it covers

  • Files at rest on untrusted storage
  • Transport through untrusted channels
  • Silent modification of ciphertext
  • Password guessing slowed by PBKDF2
LIMITS

What it cannot cover

  • A compromised device or browser
  • Malware or a keylogger
  • A weak or reused password
  • Losing the password or keyfile
Operational advice

Use a long, unique password, store the keyfile separately from the encrypted file, and keep an offline backup. Because there is no backend, recovery is entirely your responsibility.

Implementation notes

  • Encryption streams plaintext in 1 MB slices; decryption currently reads the full container into memory.
  • Each chunk receives a new 12-byte IV to avoid IV reuse across blocks.
  • Chunk length is validated before slicing to reject malformed containers.
  • Wrong credentials and tampered ciphertext fail with a clear error.
  • The app uses the browser's native Web Crypto API rather than a JavaScript cipher implementation.
09

Deployment

Both the app and this documentation site run as static assets on Cloudflare Workers, deployed with the cf CLI.

deploy
# Deploy the main app (from the repository root)
npm run build
cf deploy

# Deploy the documentation site
cd docs-site
npm install
npm run build
cf deploy
Custom domains

cloudflare.config.ts declares each Worker's custom domain. Cloudflare creates the DNS record and certificate when the Worker is deployed.

10

FAQ

Can I recover a file without the keyfile?

No. If a keyfile was used during encryption, the exact same file is required. The key material includes its SHA-256 hash.

Does AegisCrypt send anything to a server?

No. The deployed app is a static bundle. Encryption, decryption, and key derivation happen in the browser.

Why does decryption fail with the right password?

The keyfile probably differs, or the container was modified. GCM authentication rejects both cases.

Are large files supported?

Encryption streams in 1 MB chunks and avoids a single giant allocation. Very large containers can still be limited by browser memory during decryption.

Which browsers are supported?

Any modern browser with the Web Crypto API, including Chrome, Edge, Firefox, and Safari.

Ready to seal a file?

Open the app and start a local-only session.

Launch AegisCrypt →