Synchronization Security Overview

This document describes encryption schemas used by Termius to encrypt personal data and data shared with a team. Termius encrypts: SSH server and telnet configs, snippets, meta info like tags and labels, credentials for SSH and telnet authentication (when ‘Sync keys and identities’ is enabled), i.e. SSH keys, username, and password.

Personal data encryption

Termius uses RNCryptor library for encrypting a user’s personal data.

Implementations:

  • Android: custom one.

  • Desktop: custom one.

RNCryptor uses PBKDF2 with 10,000 rounds, encrypt-then-mac HMAC, and AES256-CBC with a random IV. For all data, Termius uses a single encryption key and HMAC key. Salts are generated on the Sync server.

The encryption and HMAC keys are stored on the device. Encryption and HMAC keys are stored in:

  • iOS: Keychain.

  • Android: shared preferences, encrypted by a key stored in Android KeyStore.

  • Desktop: Electron IndexedDB encrypted by a key stored in OS KeyChain when KeyChain is available and in IndexedDB as a fallback.

Shared data encryption

Termius uses hybrid encryption for team shared data:

  1. Each team member and the team admin has a key pair used for personal data encryption.

  2. The team admin generates a team encryption key.

  3. The team admin exchanges the team encryption key with each team member by encrypting the key using a team member's public key and utilises the team admin’s private key for creating a MAC.

  4. A team member decrypts the exchanged team encryption key with the private key and uses the team admin’s public key to verify the MAC.

Team Key Exchange Diagram

The encryption of shared data and personal data uses the common schema for the following reasons:

  1. Enabling a new feature for restoring account when the password is lost.

  2. Preventing re-encryption of the whole database on password change. Our experience shows that this is an error-prone action.

Technical details

We use libsodium for encrypting the team shared data and are planning to use it for personal data. We use the 1.0.17 version of libsodium and implemented our C++ binding for iOS, Android, and Desktop applications. We use the following APIs in the libsodium:

  • For public-key encryption: crypto_box_keypair, crypto_box_easy and crypto_box_open_easy – it uses X25519 key exchange, XSalsa20 stream cipher, and Poly1305 MAC.

  • For secret key encryption: crypto_secretbox_keygen, crypto_secretbox_easy, crypto_secretbox_open_easy – it uses XSalsa20 stream cipher and Poly1305 MAC.

  • For password hashing: crypto_pwhash with options: OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE, and ARGON2ID13.

  • For generating a nonce: randombytes_buf.

The encryption key and key pair are stored on the devices.

The encryption keys are stored in:

  • iOS: Keychain.

  • Android: shared preferences encrypted by a key stored in Android KeyStore.

  • Desktop: Electron IndexedDB encrypted by a key stored in OS KeyChain when KeyChain is available and in IndexedDB as a fallback.

Want to report a security concern?

Please, email us at security@termius.com.