Your family archive travels locked.

Every .heritg backup is encrypted before it leaves the exporting app. A password is optional: leave it empty for an archive that opens automatically, or add one to keep the file private from anyone who obtains it.

An empty password keeps one authenticated format across platforms, but it is not a secret and provides neither confidentiality nor authenticity against someone holding the file.

One encrypted format—with an optional secret.

The readable family tree exists at the two ends: inside the app that creates the backup and inside the app that successfully imports it. Between those ends, every current .heritg file contains authenticated encrypted bytes. Password-protected backups add end-to-end confidentiality between those trusted endpoints.

This differs from a messaging service. HERITG does not upload this backup to a family-data server. You choose where the file goes—such as local storage, your own cloud drive, or directly to another person—and, when you set one, share the password through a separate channel.

From family tree to sealed archive

Each export follows the same five-stage contract on iOS, Android, and the web. The steps are ordered because every later guarantee depends on the earlier one.

  1. 1

    Pack one portable archive

    HERITG writes the tree, people, relationships, and media into a strict ZIP payload. A SHA-256 checksum list covers every payload entry before encryption.

    manifest.json · tree.json · people.jsonl · relationships.jsonl · media/
  2. 2

    Turn the optional password into a key

    The password is normalized to Unicode NFC and processed with PBKDF2-HMAC-SHA256 for 600,000 iterations. An empty password is processed as an empty UTF-8 byte string. A new 16-byte random salt makes every export derive a different key.

    optional password + random salt -> 256-bit key
  3. 3

    Encrypt and authenticate

    AES-256-GCM encrypts the complete ZIP with a fresh 12-byte random nonce. The format header is authenticated too, so changing its version, algorithm, work factor, salt, or nonce breaks authentication.

    ZIP + header -> AES-256-GCM -> sealed bytes
  4. 4

    Move one sealed file

    The resulting .heritg file always contains encrypted bytes. A non-empty password keeps the records confidential and prevents a file holder from forging a valid replacement; an empty password does neither, because anyone can derive the same key.

    HTGENC01 · header · ciphertext · authentication tag
  5. 5

    Authenticate before import

    The destination app first tries the empty password. If that authenticates, import continues without a prompt; otherwise the app asks for the password. It verifies every checksum and graph reference before committing any family data.

    all checks pass → atomic import

The promise is in the source

The excerpt below is abridged from the actual path used for every web .heritg export, including an empty password. It asks the browser’s Web Crypto implementation to derive a non-extractable AES key and authenticate both the header and payload. The link opens the complete implementation.

web/src/heritgArchive.tsOpen exact lines
// Password → key
const material = await crypto.subtle.importKey(
  "raw", passwordBytes, "PBKDF2", false, ["deriveKey"]
);
const key = await crypto.subtle.deriveKey(
  { name: "PBKDF2", hash: "SHA-256", salt, iterations: 600_000 },
  material,
  { name: "AES-GCM", length: 256 },
  false,
  ["encrypt", "decrypt"]
);

// Header + ZIP → authenticated ciphertext
const sealed = await crypto.subtle.encrypt(
  { name: "AES-GCM", iv: nonce, additionalData: header, tagLength: 128 },
  key,
  zip
);

Implementation note: Android archive encryption uses Java Cryptography Architecture primitives and SecureRandom; the password-derived archive key is not stored in Android Keystore.

Prompt-free import path: Each app first authenticates with the empty password. These links show the exact decision that restores immediately or asks for a non-empty password.

The file says how to open it—never the password

The first 44 bytes are a versioned, authenticated envelope header. These values are safe to store beside the ciphertext; they describe how to derive the key but do not contain a password or key. An empty password remains publicly guessable by definition.

8 bytesMagicHTGENC01
2Version0001
2KDF + cipher01 01
4Iterations600000
16Random saltnew/export
12Random noncenew/export
variableEncrypted ZIPciphertext + 16-byte tag

All 44 header bytes are authenticated as AES-GCM additional data. Any unsupported or changed parameter is rejected before import.

Two vectors, asserted on three platforms

A synthetic test archive fixes the date, salt, and nonce. All three source suites assert the same complete encrypted file hashes for both NFC-equivalent non-empty passwords and the empty-password path. This proves the compulsory envelope remains byte-compatible across iOS, web, and Android.

Expected encrypted archive SHA-256 2806b437258da23ca3e0f1f57df81ae69467869ed9d9e8e0c84e00cb9bcd2780
Expected empty-password archive SHA-256 bc8df41b6991455fdad8150c610e56f32d0146ee117bbb7cb2636d3732595440

What this protects—and what it cannot

Encryption is strongest when its boundary is clear. HERITG protects the backup file between trusted endpoints; it cannot make an unlocked or compromised endpoint safe.

Protected by the encrypted backup

  • Family records and photos inside the exported archive when a non-empty password is used
  • Detection of accidental or unauthenticated changes to the header, ciphertext, or tag
  • Detection of changed, missing, extra, or corrupted payload files

Outside the encryption boundary

  • An empty password, which provides no confidentiality or authenticity against someone holding the file
  • A weak, reused, shared, or exposed password
  • Malware or an attacker controlling an unlocked device or browser
  • Readable GEDCOM, image, SVG, or legacy unencrypted archives
  • Password loss—HERITG has no recovery key or password escrow
Choose convenience or confidentiality deliberately.

Leave the password empty when automatic import matters more than file secrecy. To keep the archive private, use at least 8 characters with an uppercase letter, a lowercase letter, and a number. A longer, unique password is safer because anyone holding the file can guess passwords offline. Store it safely; HERITG has no recovery key.

Don’t take the lock icon on trust.

Read the implementation, run the compatibility tests, and inspect the security rules that keep all three platforms aligned.

Review HERITG on GitHub