Security Whitepaper
A complete technical overview of how Inventry protects your data using zero-knowledge, end-to-end encryption.
Last updated: January 2026 · v2.0
Contents
1Overview
Inventry is built on a zero-knowledge security model. This means:
- ✓Your asset data is encrypted on your device before it ever leaves your phone.
- ✓Inventry's servers never see your unencrypted data.
- ✓Even if our database is breached, attackers get indecipherable ciphertext.
- ✓We cannot comply with data requests for your asset details—we don't have them.
⚠️ Critical: No Email-Only Recovery
Because we use true zero-knowledge encryption, we cannot recover your data if you lose both your password AND your Recovery Key. Email-based "forgot password" resets require your Recovery Key to restore access to encrypted data. Save your Recovery Key in a safe place.
2Zero-Knowledge Architecture
Your Master Key never leaves your device. Our servers store only encrypted blobs and a "wrapped" (encrypted) copy of your Master Key that only you can unlock.
3Encryption Specification
Algorithm: AES-256 (Advanced Encryption Standard) Mode: CBC (Cipher Block Chaining) Padding: PKCS7 Key Size: 256 bits IV: 128-bit random IV per encryption operation Integrity: HMAC-SHA256 (Encrypt-then-MAC) Key Separation: Distinct keys for encryption vs. authentication Format: IV:Ciphertext:HMAC
✓ Authenticated Encryption (Encrypt-then-MAC)
Every piece of encrypted data includes an HMAC integrity tag. This prevents tampering attacks—if anyone modifies the ciphertext, decryption will fail rather than produce corrupted data. We use key separation: the encryption key and MAC key are derived separately, following cryptographic best practices.
AES-256 is the gold standard for symmetric encryption. It's the same algorithm used by:
4Master Key Architecture
Inventry uses a key-wrapping architecture similar to 1Password. Your password doesn't directly encrypt your data—instead, it unlocks a Master Key that does the actual encryption.
Key Derivation: PBKDF2-SHA256 Iterations: 150,000 (production) Salt: SHA256(userId) - unique per user Wrapping Key: 256-bit (encrypts Master Key) Master Key: 256-bit random (encrypts all data) // Password change is fast: // Only re-wrap Master Key with new Wrapping Key // No need to re-encrypt all your data
Why Key Wrapping?
Password changes are instant. When you change your password, we only re-wrap the Master Key with your new Wrapping Key. We don't need to re-encrypt gigabytes of photos and assets. This is the same architecture used by 1Password and other security-focused apps.
5Vault Sharing
When you share a vault with a family member, we use a Secure Invite Token system to transfer the Vault Key without exposing it to our servers.
Generate Invite
Your app generates a random Share Token (256-bit). This token is displayed as a code or QR.
Wrap Vault Key
A Share Wrapping Key is derived using PBKDF2(recipientEmail + shareToken). The Vault Key is encrypted with this, plus an HMAC for integrity.
Recipient Accepts
Your spouse enters the Share Token. Their app derives the same Share Wrapping Key (using their email + the token), unwraps the Vault Key, and stores it encrypted with their Master Key.
ShareToken = random(256 bits)
ShareKey = PBKDF2(recipientEmail + shareToken, salt, 150000)
// Owner encrypts:
WrappedVaultKey = AES(VaultKey, ShareKey)
HMAC = HMAC-SHA256(WrappedVaultKey, ShareKey)
Store: { wrapped_key, hmac, share_token_hash }
// Recipient derives same ShareKey, verifies HMAC, unwraps VaultKeyServer Never Sees Vault Key
The Share Token is exchanged out-of-band (shown on your screen, entered on theirs). Our server stores only the hash of the token for lookup, not the token itself. Without the token, the encrypted Vault Key is useless.
6Data Storage
● What's Encrypted
- • Asset titles & descriptions
- • Serial numbers & VINs
- • Purchase prices & dates
- • Notes & custom fields
- • Photos (encrypted blobs)
- • Receipt images
● What's NOT Encrypted
- • Your email address
- • Subscription status
- • Category labels (for filtering)
- • Timestamps (for sync)
- • Wrapped Master Key (encrypted)
Photo Encryption
Photos are encrypted using keys derived from your Master Key with domain separation:
PhotoMacKey = HKDF(MasterKey, "photo-mac")
EncryptedPhoto = IV + AES(Photo, PhotoEncKey) + HMAC(ciphertext, PhotoMacKey)
📱 On-Device Viewing
When you view photos in the app, they are decrypted on your device and cached in the app's private sandbox for faster access and offline viewing. This cache is protected by your device's operating system security (iOS App Sandbox / Android App Sandbox) and is deleted when you uninstall the app. Photos are always encrypted in transit and at rest on our servers—we never see your unencrypted photos.
7Recovery Key (Critical)
⚠️ Read This Carefully
Your Recovery Key (format: INVT-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX) is the only way to restore access to your encrypted data if you forget your password.
If you lose both your password AND your Recovery Key, your data is permanently lost. We cannot help you.
✓ Change Password (Logged In)
If you're logged in and want a new password:
- Enter your current password
- Your Master Key is unwrapped
- Master Key is re-wrapped with new password
- Done—no data re-encryption needed
⚠️ Forgot Password
If you forgot your password, you must have your Recovery Key:
- Reset your Supabase auth password via email
- Enter your Recovery Key in the app
- Recovery Key unwraps your Master Key
- Master Key is re-wrapped with new password
How Recovery Key Works
When you create your account, Inventry generates both a Password-Wrapped Master Key and aRecovery-Wrapped Master Key. These are two separate "copies" of your Master Key, each wrapped with a different secret.
MasterKey = random(256 bits) // Two ways to unwrap the same Master Key: PasswordWrappedKey = AES(MasterKey, PBKDF2(password, userId)) RecoveryWrappedKey = AES(MasterKey, PBKDF2(recoveryKey, "recovery:" + userId)) // Both are stored on server. Either one can unwrap MasterKey.
The app provides a "Recovery Kit" you can print. It contains your email and Recovery Key. Store it in a physical safe, safety deposit box, or with your estate documents. Do not store it digitally.
8Libraries & Standards
We use industry-standard, well-audited libraries. We do not implement our own cryptographic primitives.
| Library | Purpose |
|---|---|
| crypto-js | AES-256-CBC, PBKDF2-SHA256, HMAC-SHA256 |
| expo-crypto | Cryptographically secure random number generation (CSPRNG) |
| expo-secure-store | iOS Keychain / Android Keystore for local key storage |
Randomness
All cryptographic random values (Master Key, IVs, Share Tokens) are generated usingexpo-crypto, which uses the platform's native CSPRNG (SecRandomCopyBytes on iOS, SecureRandom on Android). In development builds without native modules, the app will refuse to generate keys rather than fall back to insecure randomness.