Security Basics
ZestSSH is an SSH client, which means it handles private keys, passwords, and remote server access. This page covers the security features built into the app and how to configure them. All of these features are free — security is not paywalled.
PIN lock
Section titled “PIN lock”You can set a numeric PIN that must be entered every time you open ZestSSH. Go to Settings > Security and choose PIN as the lock method.
How the PIN is stored
Section titled “How the PIN is stored”Your PIN is never stored in plaintext. ZestSSH hashes it with Argon2id using the following parameters:
- Memory: 4 MB
- Iterations: 4
- Parallelism: 2
- Hash length: 32 bytes
- Salt: 16 bytes, randomly generated per PIN
The stored value is base64(salt):base64(hash) in the platform’s secure storage. Argon2id is a memory-hard key derivation function that resists GPU and ASIC-based brute-force attacks.
Brute-force protection
Section titled “Brute-force protection”After 5 consecutive wrong PIN entries, ZestSSH locks you out with escalating delays:
| Failed attempts | Lockout duration |
|---|---|
| 5 | 30 seconds |
| 10 | 60 seconds |
| 15+ | 5 minutes |
The lockout state is persisted to secure storage. Restarting the app does not reset the lockout timer or the failed attempt counter. The counter resets only on a successful PIN entry.
PIN verification also uses constant-time comparison to prevent timing side-channel attacks.
Legacy PIN migration
Section titled “Legacy PIN migration”If you set a PIN in an older version of ZestSSH (which used unsalted SHA-256), the hash is automatically migrated to Argon2id on your next successful unlock. No action is required.
Biometric lock
Section titled “Biometric lock”If your device supports biometric authentication (fingerprint, face recognition), you can use it instead of or in addition to a PIN. Go to Settings > Security and choose Biometric or Both.
ZestSSH uses the local_auth package, which delegates to:
- Android: BiometricPrompt API (fingerprint, face, iris).
- iOS: Face ID or Touch ID.
Biometric data never leaves your device. ZestSSH does not store or process biometric templates — it asks the OS to verify your identity and receives a pass/fail result.
Auto-lock timeout
Section titled “Auto-lock timeout”You can configure how quickly ZestSSH locks after you leave the app. The timeout is set in minutes (0 = lock immediately when backgrounded). This applies to both PIN and biometric lock methods.
Host key verification (TOFU)
Section titled “Host key verification (TOFU)”ZestSSH uses the Trust On First Use model for host key verification. When you connect to a server for the first time, the app shows the server’s key type and SHA-256 fingerprint and asks you to accept or reject it.
Once you accept a host key, it is stored in ZestSSH’s known hosts database with:
- Host address and port.
- Key type (e.g.,
ssh-ed25519,ssh-rsa). - SHA-256 fingerprint.
- First-seen and last-seen timestamps.
Key change detection
Section titled “Key change detection”On subsequent connections, ZestSSH compares the server’s presented key against the stored fingerprint. If the key has changed, you see a warning. This could indicate a server reinstallation or a man-in-the-middle attack.
ZestSSH also detects key-type changes. If a server previously used ssh-rsa and now presents ssh-ed25519, that is treated as a changed key. This prevents an attacker from bypassing fingerprint checks by presenting a different algorithm.
Best practice
Section titled “Best practice”Always verify host key fingerprints out-of-band (e.g., from your hosting provider’s dashboard or from a console session on the server) before accepting them. The TOFU model is only as strong as your first connection.
Encrypted backups
Section titled “Encrypted backups”ZestSSH exports backup files with the .zest extension. These contain all your connections, identities, known hosts, snippets, and connection groups.
Encryption details
Section titled “Encryption details”All backups are encrypted with AES-256-GCM using a key derived from your backup password via Argon2id (same parameters as cloud sync). There is no option to create an unencrypted backup — an unencrypted dump of SSH credentials and private keys would be a serious security risk on shared or lost devices.
The backup password must be at least 12 characters. Shorter passwords are rejected.
What is in a backup
Section titled “What is in a backup”A .zest file contains a serialized snapshot of:
- All saved connections (hostname, port, username, authentication method).
- All identity key pairs (private and public key material).
- Known hosts database (fingerprints, key types).
- Snippets (saved commands).
- Connection groups.
Restoring a backup
Section titled “Restoring a backup”Go to Settings > Backups > Import and select a .zest file. Enter the backup password to decrypt and restore. If you enter the wrong password, decryption fails and no data is modified.
Cloud sync threat model
Section titled “Cloud sync threat model”ZestSSH offers optional cloud sync (a paid feature) that synchronizes your data across devices. The full cloud sync security model is covered in a separate document, but the key points are:
- All data is encrypted client-side before it leaves your device.
- Encryption uses AES-256-GCM with a key derived from your sync password via Argon2id.
- The server never sees your plaintext credentials, keys, or connection details.
- Authentication uses Firebase Auth (Google or Apple sign-in) for identity verification.
- You can change your sync password at any time, which re-encrypts all synced data.
The sync server cannot decrypt your data. If you forget your sync password, your cloud data is unrecoverable.