Encrypted Backups
ZestSSH backup files use the .zest format. All backups are encrypted — there is no option to export an unencrypted dump. Storing plaintext SSH credentials, private keys, and known hosts in user-accessible storage would be a serious security risk if the device is shared, lost, or scanned by another app.
This is a free feature — not paywalled.
File Format
Section titled “File Format”Every .zest file has the following binary structure:
| Offset | Size | Content |
|---|---|---|
| 0 | 4 bytes | Magic bytes: ZEST (ASCII) |
| 4 | 1 byte | Version byte |
| 5 | Variable | Encrypted payload |
Version Byte
Section titled “Version Byte”| Version | Meaning |
|---|---|
1 | Encrypted (current) — AES-256-GCM with Argon2id-derived key |
2 | Legacy unencrypted JSON (import-only, never generated by current builds) |
Encrypted Payload (Version 1)
Section titled “Encrypted Payload (Version 1)”The encrypted payload is structured as:
salt(32 bytes) + IV(12 bytes) + GCM tag(16 bytes) + ciphertext- Salt: 32 random bytes used for Argon2id key derivation.
- IV: 12-byte AES-GCM initialization vector.
- GCM tag: 16-byte authentication tag for integrity verification.
- Ciphertext: zlib-compressed JSON, encrypted with AES-256-GCM.
Encryption Process
Section titled “Encryption Process”- All app data is gathered via
SyncDataService.gatherAll()into a JSON map. - A 32-byte random salt is generated.
- The user’s backup password is run through Argon2id with the salt to derive a 256-bit key (same parameters as Cloud Sync: 64 MB memory, 3 iterations, 4 parallelism).
- The JSON is zlib-compressed and encrypted with AES-256-GCM using the derived key.
- The output is prefixed with the
ZESTmagic bytes and version1.
Password Requirements
Section titled “Password Requirements”- Minimum length: 12 characters
- Empty or short passwords are rejected before any encryption occurs.
- The 12-character minimum is enforced because backups land in user-accessible storage (Downloads folder, Files app), where the password is the only barrier against an offline attacker.
What’s Included
Section titled “What’s Included”A backup contains everything needed to fully restore your ZestSSH configuration:
| Data | Included |
|---|---|
| Connections (host, port, settings, groups) | Yes |
| Identities (usernames, auth methods) | Yes |
| Identity secrets (passwords, private keys) | Yes (encrypted) |
| Connection groups | Yes |
| Known hosts (fingerprints) | Yes |
| Snippets | Yes |
| Port forward rules | Yes |
Data that is not included:
- Terminal transcripts / session recordings
- Automation history / audit logs
- App settings and preferences
- Theme customizations
Export Flow
Section titled “Export Flow”- Go to Settings > Backup & Restore > Export Backup.
- Enter a backup password (minimum 12 characters).
- ZestSSH encrypts all data and writes the
.zestfile.
File Location by Platform
Section titled “File Location by Platform”| Platform | Location |
|---|---|
| Android | /storage/emulated/0/Download/ |
| iOS | Application Documents (accessible via the Files app) |
| Desktop (Windows/macOS/Linux) | Documents/ZestSSH/backups/ |
Filename Format
Section titled “Filename Format”- Manual backups:
zestssh_backup_YYYY-MM-DDTHH-MM-SS.zest - Auto-backups:
zestssh_auto_YYYY-MM-DDTHH-MM-SS.zest
Import Flow
Section titled “Import Flow”- Go to Settings > Backup & Restore > Import Backup.
- Select a
.zestfile. - Enter the backup password.
- ZestSSH decrypts and restores the data.
Import Behavior
Section titled “Import Behavior”- Additive merge: Local data is NOT deleted. Existing records are updated, new records are inserted. This is an upsert, not a replace.
- Identity secrets are restored to Flutter Secure Storage after the database transaction succeeds, preventing orphaned secrets if the transaction rolls back.
- Legacy v2 backups (unencrypted) are accepted for backward compatibility but trigger a UI warning urging the user to re-export with a password.
Import Size Limit
Section titled “Import Size Limit”Files larger than 50 MB are rejected before loading into memory to prevent out-of-memory crashes from malicious or corrupted files.
Error Handling
Section titled “Error Handling”| Error | Cause |
|---|---|
| ”Invalid backup file format” | Missing or incorrect ZEST magic bytes |
| ”This backup is password-protected” | Version 1 file but no password entered |
| ”Wrong password or corrupted backup” | AES-GCM decryption failed (wrong key or tampered data) |
| “Unsupported backup version” | Unknown version byte |
| ”Backup file is too large (max 50 MB)“ | File exceeds the safety limit |
| ”Backup file not found” | File path does not exist |