PrivShare

Crypto spec

Cryptographic Specification

This page documents the implemented cryptographic construction. It avoids phrases like military-grade encryption because those phrases do not let a security engineer evaluate the design.

Fragment-Key Text And Env Shares

Text and environment-variable shares use one random content key per share.

  • Content key: 32 random bytes from crypto.getRandomValues.
  • Encryption: AES-GCM through the browser Web Crypto API.
  • IV/nonce: 12 random bytes per encryption operation.
  • Plaintext format: JSON payload, UTF-8 encoded.
  • Text/env serialized payload cap: 200 KiB.
  • Key verifier: SHA-256 digest of the raw 32-byte share key.
  • Key transport: URL fragment, using #key=...
  • Ciphertext, IV, key, and verifier encoding: canonical unpadded base64url.

File Shares

File bundles use one random AES-GCM bundle key. File bytes and file metadata are encrypted separately.

  • Bundle key: 32 random bytes from crypto.getRandomValues.
  • File body encryption: AES-GCM through Web Crypto.
  • File metadata encryption: AES-GCM through Web Crypto.
  • IV/nonce: 12 random bytes for each file body and each metadata record.
  • Metadata before encryption: filename, MIME type, size, and last modified timestamp.
  • Current limits: 1 file with 10 MiB plaintext without an account, or 1 to 10 files with 20 MiB aggregate plaintext with a Free account.
  • Transfer: signed CloudFront upload and download URLs for ciphertext bytes.
  • Server/S3 do not receive plaintext files, plaintext filenames, plaintext MIME types, raw keys, or URL fragment keys.

Password-Protected Shares

Password mode wraps the random share key. It does not replace the random content key with direct password encryption.

  • Password rule: at least 12 non-whitespace characters at creation.
  • KDF: PBKDF2-HMAC-SHA-256 through Web Crypto.
  • Iterations: 600,000.
  • Salt: 16 random bytes.
  • Derived output: 64 bytes.
  • Bytes 0-31 become the AES-GCM wrapping key.
  • Bytes 32-63 are hashed with SHA-256 to create the server-stored password verifier.
  • Wrapping: the raw 32-byte share key is encrypted with AES-GCM and a 12-byte random wrapping IV.
  • Format version: pbkdf2_sha256_v1.
  • Recipient link: keyless /s/[id] URL.
  • Limitation: wrapped-key metadata permits offline password guessing if obtained, so strong passwords still matter.

Server-Visible Cryptographic Metadata

The server needs enough metadata to store ciphertext, enforce lifecycle rules, and authorize retrieval without learning plaintext.

  • Fragment-key shares: ciphertext, IV, key verifier, lifecycle settings, kind, and approved metadata.
  • Password shares: ciphertext, IV, password verifier, KDF version, iteration count, salt, wrapping IV, wrapped share key, lifecycle settings, kind, and approved metadata.
  • File shares: encrypted metadata, ciphertext sizes, IVs, opaque object keys, lifecycle settings, and approved metadata.
  • The server does not receive plaintext share contents, plaintext files, plaintext share passwords, private decryption keys, or URL fragment keys.

Implementation References

These are source locations in the repository. They are not a public audit claim.

Text/env crypto:
src/lib/share-crypto.ts

File crypto:
src/lib/share-file-crypto.ts

Password wrapping:
src/lib/share-password.ts

Client API serialization:
src/lib/share-client.ts