Technical documentation for security researchers, IT officers and customers who want to know exactly what gets encrypted, how, and why.
Revier3D encrypts all hunting data client-side before it reaches the server. The server is a dumb, encrypted storage: it sees only ciphertext and cannot decrypt it. It does not know where your boundary is, not what you harvested.
Architecture: row-level encryption instead of per-field _enc columns. Each row is stored as a single encrypted JSON blob (data_enc). The server sees only metadata (id, revier_id, created_at, updated_at, deleted_at, vvec) for sync and tenant isolation. All fields (coordinates, game species, date, name, note, etc.) are in the blob.
The Revier Key (RK) is generated once at setup as 256-bit random and is not derived from the password; instead it is wrapped with a key derived from the password (KEK). This allows password changes without making data unreadable.
What the server ultimately knows: account email (login), Paddle payment data (billing), hunting-ground slug (URL), hunting-ground status (access control), storage used (quota). No hunting data, not even the position. Even 3D terrain and aerial imagery are encrypted.
There is no operator emergency key and no backdoor, not even during the beta. The only debugging path is the "Report error with data" button (section 6).
revier.kek_salt)Why not PBKDF2 or scrypt? PBKDF2 is GPU- and ASIC-friendly and therefore inferior for password-based keys today. scrypt is a strong alternative, but Argon2id is the winner of the 2015 Password Hashing Competition with broader library support. The hybrid mode (id) protects both against side-channel attacks (memory-hard at the front) and GPU cracking (time-hard at the back).
Deliberately memory-hungry. 64 MiB per attempt makes mass cracking on GPUs uneconomical. On a user's end device 64 MiB is a negligible load; for an attacker with millions of attempts it is a volume-limiting barrier.
crypto.subtlecrypto.subtle.importKey(extractable:false) in the browser's secure key store. JavaScript can use it but never read it.Why AES-GCM via WebCrypto instead of XChaCha20? Three reasons. First: crypto.subtle allows extractable: false; the key never leaves the browser's secure key store. An XSS attack can encrypt/decrypt data while the tab is open but cannot steal the key. That is the single most important step for maximum security. Second: AES-NI hardware acceleration makes AES-GCM faster than XChaCha20 in software on most devices. Third: nonce as counter (96 bit) completely eliminates nonce reuse, the only catastrophic failure mode in GCM.
crypto.subtleWhy P-256 instead of X25519? X25519 is not yet supported by WebCrypto in all browsers (not Safari). P-256 is universally supported and can be imported as non-extractable. The non-extractable gain outweighs the theoretical X25519 advantage. P-256 is the TLS standard for Apple, Google, Microsoft.
crypto.subtle.deriveBitsRK_data (rows), RK_cam (camera file keys), RK_meta (index/cache). If one subkey leaks, the others are safe.# Generated once when the hunting ground is created: RK = random(256 bit) # Revier Key, generated ONCE, then constant # Key separation via HKDF (purpose-specific subkeys): RK_data = HKDF(RK, "data") # Row encryption (AES-256-GCM) RK_cam = HKDF(RK, "camera") # Camera file key decryption (ECDH P-256) RK_meta = HKDF(RK, "metadata") # Index/cache # Wrapping 1: hunting-ground password (single mode, four friends share link+pw) KEK = Argon2id(hunting_ground_pw, revier.kek_salt, m=64 MiB, t=3, p=1) revier.rk_wrapped = AES-256-GCM(Enc, RK, KEK) # via crypto.subtle # Wrapping 2 (optional): accounts (multi mode, per member) revier.rk_wrapped_account[i] = ECDH-Seal(RK, account_pubkey[i]) # P-256 via crypto.subtle # NO operator emergency key. No backdoor. The promise applies from day 1. # Data encryption (per entry): file_key = random(256 bit) cipher = AES-256-GCM(Enc, plaintext, file_key, nonce=counter) # via crypto.subtle wrapped_file_key = ECDH-Seal(file_key, revier.pubkey) # camera inbound # All key handles are non-extractable (extractable:false).
The separation between RK (constant) and KEK (from password) solves the main problem of a derivation-based architecture: password change costs no data. A password change means only that the single wrapping rk_wrapped gets regenerated, a small blob operation. The encrypted data itself is never touched.
rk_version carries the key generation. At beta end the RK gets rotated and the entire stock is re-encrypted with the new RK: only then is an old, possibly compromised RK worthless.
Per table with encrypted fields (marker, foto, strecke, ansitz, wartung, schaden, belegung, buchung, sketch, kontrolle, nachsuche, fuetterung_log) new columns appear:
<field>_enc: ciphertext (Base64), replaces the previous clear-text fieldkek_salt: per hunting ground (in revier), 128 bitrk_wrapped: in revier, wrapping 1 (hunting-ground password)rk_wrapped_account: in revier_membership, per account (ECDH P-256)rk_version: int, key generationpubkey: in revier, public P-256 keye2ee_aktiv: bool, migration can happen in stagesExisting hunting grounds migrate lazily: on first read after the update, the client decrypts the clear text from the legacy column, re-encrypts it with RK and writes it back into <field>_enc. Cloudflare cache (4 hours) and old clients can coexist in this phase; the legacy column stays until wave 3.
The route /foto/<id> delivers ciphertext starting in wave 2. A service worker (sw.js) intercepts the request, decrypts client-side and returns a normal response. This keeps <img src="/foto/…"> in HTML unchanged, and native lazy-loading, caching and memory management of the browser continue to work.
There is no operator emergency key, no administrative access, no backdoor. The promise "we cannot look inside" applies from day 1, not only after a beta phase.
For debugging encrypted errors there is the "report error with data" button: the client packs the broken record with surrounding context, encrypts it with the public operator key and uploads it. The operator can read exactly this one record with their private key on their machine. They have no standing access to any hunting-ground data.
This procedure remains after the beta and is the only debugging path.
Encryption that promises everything lies. The following data stays clear text, the minimum without which the server cannot function:
Concrete consequence: the server does not know where your boundary is, not where a marker stands, not what you harvested. It knows only: "Account #31 pays for Hunting Ground #71, which uses 2.3 GB."
Further conceptual limits:
admin_enter disappears. Support runs via instructions and a "report error with data" button that uploads broken records asymmetrically encrypted./stb/<token>#<key> (fragment key, browser decrypts locally). On key loss, ledger data is also irrecoverable, this must be in the terms."Trust us" is not enough for encryption. Four levels, ascending in persuasiveness:
/sicherheit shows the logged-in user their own data side by side: left what the browser shows, right the raw row as it really stands in the database. The user sees alphabet soup with their own eyes. Plus, honestly: a second table with what is not encrypted.Deliberately not: an external audit (Cure53 and others). Too expensive for the current stage, not necessary without paying customers. May follow later and is declared in this whitepaper as "not performed", not concealed.
Market research August 2026, measured rather than claimed. Evidence in PLAN-APP-SYNC-E2EE.md part A.
| Provider | Encryption promise | Source |
|---|---|---|
| Revierwelt (market leader) | No E2EE promise measurable. Apple privacy notes declare location, photos, identity, all linked to user identity. | App Store |
| Waidly | No cloud at all, everything local on the device, no registration. 12.99 € one-time. Trade-off: no sharing, no backup, no web, no 3D. | iphone-ticker |
| RevierBuch, JagdCom, Mein Revier | Generic "data security", no E2EE promise beyond TLS. | Provider pages |
| Jagdgefährte | "Encrypted chat". Refers to communication, not hunting-ground data. | Store description |
| CoHunt (international) | E2EE for peer-to-peer communication (mesh chat); hunting-ground data is not stored centrally (no account, no cloud storage). The promise covers communication, not cloud-stored hunting-ground data. | Vendor privacy policy 03/2026 |
| HuntStand, onX Hunt (international) | No E2EE or zero-knowledge promise found. | Market overviews 2026 |
| Signal, Matrix | E2EE for communication. Not designed for hunting-ground data and 3D maps. | Project pages |
Defensible wording: No cloud-based hunting app was found that promises end-to-end encryption for hunting-ground data.
Revier3D positions itself between Waidly (local, isolated) and Revierwelt (cloud, observable): private like an offline app, but still shareable, backed up and reachable from anywhere.
This section examines whether full encryption is compatible with Austrian law and the GDPR. The assessment is based on the legal situation as of August 2026 and does not replace legal advice in individual cases.
The Austrian Constitutional Court (VfGH) declared data retention unconstitutional in 2014. There is no statutory requirement for web applications to store IP addresses. Revier3D is not a telecommunications provider under the TKG. Not storing IP addresses is not only legal but required by data protection law (GDPR Art. 5(1)(c), data minimization).
In criminal proceedings (§ 76 StPO), authorities can demand what is available. If nothing is stored, there is nothing to hand over. You cannot be compelled to store data that you do not want to store.
The user has the right to information about the processing of their data. With E2EE, Revier3D can provide information about metadata (account, email, tariff, storage, hunting-ground ID). The encrypted content cannot be disclosed because Revier3D cannot decrypt it. The user can view the content themselves (decrypting locally). Art. 15 is fulfilled.
The user can export their data in a structured, commonly used format. The export is client-side: the browser decrypts the data locally and generates the export format. The export is password-protected by default. Art. 20 is fulfilled.
The GDPR explicitly requires encryption as a technical and organizational measure (Art. 32(1)(a)) and privacy by design (Art. 25). Full E2EE exceeds the requirements. E2EE is not only legal but the data protection optimum.
The user has a statutory 7-year retention obligation for accounting records. With E2EE, receipts and bookings are encrypted. On key loss without recovery code, this data is irretrievably lost.
This is the user's obligation, not Revier3D's. The terms (§ 2.4) explicitly state: "The responsibility for the tax accuracy of the entries and for compliance with retention obligations (in particular § 132 BAO) lies with the customer." E2EE does not change this, but increases the risk on key loss.
Revier3D mitigates this risk through: (1) recovery code at setup, (2) encrypted export as additional backup, (3) tax advisor access via a fragment-key link.
Public authorities can seize data (§ 76 StPO) or request information. Revier3D hands over what it has: account metadata and encrypted data blocks. The encrypted content cannot be decrypted and therefore cannot be disclosed. This is comparable to ProtonMail (Switzerland) and Tutanota (Germany), both of which operate legally in German-speaking jurisdictions.
Revier3D cannot rule out that a statutory obligation to log connection data (IP addresses) may be introduced in the future. Such an obligation would apply to metadata, not to hunting data. Even then, the encrypted content would remain unreadable.
There is no Austrian legal basis that compels a software provider to weaken its encryption or build a backdoor. At EU level, the CSAR regulation ("Chat Control") is being discussed, which would provide for scanning of encrypted communication. As of August 2026 it is not adopted, targets messengers and not niche SaaS. With open code and reproducible builds, a covert backdoor would be detectable.
crypto.subtle (WebCrypto API, AES-GCM + ECDH P-256 + HKDF, non-extractable), hash-wasm (Argon2id, WASM-based), @noble/ed25519 (license signing only, wave 5).revier3d/src/crypto/ (wave 1, starting August 2026), webmap/static/revier-crypto.js.webmap/PLAN-APP-SYNC-E2EE.md in the repository.