Synchronization Security Overview
This document describes:
    The authentication process (as of Aug, 2021).
    The encryption schemas used to encrypt personal data and data shared with a team (as of Aug, 2021). Termius encrypts SSH server and telnet configs, snippets, meta info like tags and labels, credentials for SSH and telnet authentication, i.e. SSH keys, username, and password.


Termius uses the username and password authentication. After successful authentication, the app uses the password as a key for data encryption as described later in this article.

ARGON2-based SRP (New)

For authenticating in the Termius cloud, the app communicates with the server in a way that prevents sending a password or password hash over the network using a modified SRP6a protocol. The authentication process looks like this:
Authentication protocol
To complete authentication, the client and the Termius cloud must prove that each party has the same key:
    The client gets a random piece of data from the Termius cloud, salt for Argon2id password hash and User Identifier.
    The client sends its random data and client proof.
    The client gets a server proof, an encrypted API Key and a salt.
    The client validates the server proof and decrypts the API Key.

PBKDF2 with a SHA256 hash of SHA256-hashed password (Old)

For authenticating in the Termius cloud, the app calculates the SHA256 of the password and sends it using HTTPS-protected REST API. The Termius cloud calculates PBKDF2 hash using the default Django implementation.

Personal Data Encryption

Termius uses hybrid (new) encryption for personal data that has been migrated to this type of encryption, and symmetric (old) encryption for other data.

Hybrid (New) Encryption

    The app generates a key pair for the user and syncs the private key encrypted by the user password.
    Using the key pair, the app generates a personal encryption key for the user.
    The app uses the personal encryption key to encrypt personal data.

Symmetric (Old) Encryption

Personal data that hasn't been migrated to the hybrid encryption is encrypted with the RNCryptor library.
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, both derived from the password used for authentication. Salts are generated on the sync server.
The encryption and HMAC keys are stored on the device, namely in:

Shared Data Encryption

Termius uses hybrid encryption for team shared data:
    Each team member and the team admin has a key pair used for personal data encryption.
    The team admin generates a team encryption key.
    The team admin exchanges the team encryption key with each team member by encrypting the key using a team member's public key and utilizes the team admin’s private key for creating a MAC.
    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 a common schema because:
    It allows implementing an option to restore an account when the password is lost.
    It prevents re-encryption of the whole database on password change. The Termius team's experience shows that this is an error-prone action.

Technical Details

Termius uses Libsodium for encrypting team shared data and personal data that has been migrated to new encryption. Termius uses the 1.0.17 version of Libsodium and custom C++ binding for iOS, Android, and Desktop applications. Termius uses the following APIs in 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.
Termius uses SPR implementation from Botan and GRPC over TLS as a transport for SRP protocol. Termius uses the 2.14.0 version of Botan and custom C++ binding for iOS, Android, and Desktop applications.
The encryption key and key pair are stored on the devices, namely 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 [email protected].
Last modified 1mo ago