Free privacy tool

Seal a file

Encrypt a file under a fresh one-time key and send it through any channel you like. Whoever holds the key opens it right here, on this page. Nothing is ever uploaded, there is no passphrase to crack, and you see what is inside before anything is saved.

Runs entirely in this tab. This page cannot talk to any server at all.

Every parameter, stated

Cipher
AES-256-GCM (WebCrypto), 128-bit tag per chunk
Key
256 bits from the browser CSPRNG, generated fresh per seal, used once, derived from nothing
Chunking
an encrypted manifest (filename, size, type), then the file in 1 MiB chunks — each authenticated separately
Nonce
32-bit random seal salt ‖ 64-bit chunk counter — never repeated within a file, and the key is single-use anyway
Authenticated data
the full 16-byte header plus each chunk’s index and the total chunk count — reordering, truncating or splicing chunks breaks decryption
Key string
base64url, 47 characters: the 32-byte key plus a 3-byte SHA-256 checksum, so a typo fails cleanly instead of producing garbage

Honest answers about what this does

Everything happens in your browser.

Sealing and opening both read the file into this page’s memory, run AES-256-GCM there with your browser’s built-in WebCrypto engine, and hand the result back as a download. Nothing is uploaded. There is no account and no server-side processing. Unlike the rest of this site, this page doesn’t even load the cookieless visit counter. No analytics of any kind.

This isn’t just a promise. The page is served with a Content-Security-Policy that lets the browser fetch only this site’s own static files. It has no way to send your file, your key, or anything else to any server, ours included. Open your browser’s developer tools while sealing and you will see zero requests. For the bluntest proof, install the Toolbox and seal in airplane mode. With the network off, nothing can leave.

The key is everything — and we never have it.

Each seal generates a fresh random 256-bit key in your browser. It is shown to you once and kept nowhere: not in our systems (none are involved), not in your browser’s storage, not in the sealed file. There is no passphrase to guess and nothing to brute-force. Whoever holds the key and the file can open it. Whoever doesn’t, can’t.

That has a hard consequence: if the key is lost, the file is gone. There is no reset, no support ticket, no recovery. This is not us being unhelpful. A copy we could recover would be a copy someone could steal or demand.

The key link never reaches a server.

The share link puts the key after the # in the URL. That part, the fragment, stays in the browser. It is never included in what the browser sends to any server, ours or anyone’s. When this page loads with a key in the link, it reads the key, switches to the Open tab, and immediately removes the key from the address bar. So it doesn’t linger in the visible URL or in browser history.

Still, anyone who has both the link and the sealed file can open it. That’s why this page tells you to send the file and the key through different channels.

You see what’s inside before anything is saved.

Opening happens in two steps. First the page decrypts only a small manifest: the original filename, size and type. It shows you that, with a loud warning for file types that can run code (programs, scripts, installers, macro documents, HTML) and for names disguised with a double extension like invoice.pdf.exe. Nothing is written until you click to decrypt. The page never opens or renders the decrypted content itself. It only offers the file for download.

Be clear about what encryption does and doesn’t prove. A sealed file is confidential in transit. Sealing says nothing about who sent it or whether its contents are safe. Treat an unexpected sealed file as skeptically as an unexpected attachment.

Where the trust boundary really is.

You are running code this website served to you. If sealby.app or your connection to it were compromised, a malicious page could read what you put into it. This is true of every web-based encryption tool, and we’d rather say it than pretend otherwise. What we do about it: the page is a static file, and we keep it free of third-party code. The installed Toolbox lets you keep using a version you’ve already loaded. And the format is documented below, so independent tools can be built against it.

Your own device is inside the boundary too. Browser extensions with page access, or malware on the machine, can read anything any page can. The sealed file hides its contents, but not everything. Anyone holding it can see its size (roughly the original’s) and that it is a Sealby-sealed file.

Plain-language limits

  • Lost key = lost file. No exceptions, by design.
  • We can’t see your files or keys, so we also can’t scan them for malware. The file-type warning is based on the filename only. It is not a safety guarantee.
  • Anyone with both the sealed file and the key can open it. The tool doesn’t know or check who they are.
  • The sealed file’s size roughly reveals the original file’s size.
  • One file, up to 100 MB, per seal. Zip multiple files first.

The format, byte by byte

Everything a technical reader needs to verify this page’s output independently, or to open a .sealed file in thirty lines of Python:

bytesfieldcontents
0–7magicASCII "SEALBY-W"
8version0x01 — anything else is rejected as “made with a newer version”
9algorithm0x01 = AES-256-GCM
10–13seal salt4 bytes, CSPRNG, fresh per seal
14–15reservedmust be zero
16–endchunk frameseach: uint32 BE ciphertext length, then the AES-GCM ciphertext + 16-byte tag

Chunk 0 is the manifest: UTF-8 JSON {"name":…,"size":…,"type":…}. Chunks 1…N−1 are the file in 1 MiB pieces. Per chunk i of N: nonce = salt ‖ uint64 BE i; authenticated data = header ‖ uint64 BE i ‖ uint64 BE N. So tampering, truncation, reordering, relocation and cross-file splicing all fail authentication. Each case is proven by a committed negative test.

Key string: base64url (no padding) of the 32-byte key followed by the first 3 bytes of its SHA-256, 47 characters in total. A typo fails the checksum instead of producing garbage.

Reference opener (Python, cryptography library)
import base64, hashlib, json, struct, sys
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

raw = open(sys.argv[1], "rb").read()
assert raw[:8] == b"SEALBY-W" and raw[8] == 1 and raw[9] == 1
assert raw[14:16] == b"\x00\x00"
header, salt = raw[:16], raw[10:14]
frames, off = [], 16
while off < len(raw):
    (n,) = struct.unpack(">I", raw[off:off + 4]); off += 4
    frames.append(raw[off:off + n]); off += n
assert off == len(raw)

kb = base64.urlsafe_b64decode(sys.argv[2] + "=")   # 47-char key string
key, check = kb[:32], kb[32:35]
assert hashlib.sha256(key).digest()[:3] == check    # typo check

N = len(frames)
def chunk(i):
    nonce = salt + struct.pack(">Q", i)
    aad = header + struct.pack(">QQ", i, N)
    return AESGCM(key).decrypt(nonce, frames[i], aad)

manifest = json.loads(chunk(0))
data = b"".join(chunk(i) for i in range(1, N))
assert len(data) == manifest["size"]
open(manifest["name"], "wb").write(data)
print("decrypted ->", manifest["name"])

This is for files in transit. The vault is for files at rest.

Sealing protects a file on its way somewhere. Sealby protects everything that stays: photos, files and notes in encrypted vaults on your iPhone. No account, no servers, readable by no one but you.

Download on the App Store

iPhone & iPad · iOS 17+ · Free