This document describes:
- the authentication process,
- encryption schemas used for encrypting personal data and data shared with a team. Termius encrypts SSH and Telnet configs, snippets, meta info like tags and labels, SSH and Telnet credentials, i.e. usernames, passwords, SSH keys and their passphrases.
Authentication
Termius offers two types of authentication: username / password and single sign-on (SSO). After a successful authentication, the app uses password / encryption passphrase to encrypt data, as described later in the article.
ARGON2-based SRP (new)
The app uses a modified SRP6a protocol to communicate with the server without sending the password or password hash (as well as encryption passphrase and its hash) over the network. The following diagram illustrates the authentication process:
To complete authentication, the client and the Termius cloud must prove that each party has the same key:
- The cloud sends the client a random piece of data, a salt to be used by the Argon2id password hash algorithm, and User Identifier.
- The client sends the cloud a random piece of data and a client proof.
- The cloud sends the client a server proof, an encrypted API Key and a salt.
- The client validates the server proof and decrypts the API Key.
This method is used with the hybrid encryption of personal and shared data.
PBKDF2 with a SHA256 hash of SHA256-hashed password/encryption passphrase (old)
The app calculates the SHA256 of the password / encryption passphrase and sends it using HTTPS-protected REST API. The Termius cloud calculates PBKDF2 hash using the default Django implementation.
This method is used with the symmetric encryption of personal data.
Personal data encryption
Termius uses a new, hybrid encryption for personal data that has been migrated to this type of encryption, and symmetric encryption for other data.
Hybrid (new) encryption
- The app generates a key pair and syncs the private key encrypted using the user's password / encryption passphrase.
- Using the key pair, the app generates the user's personal encryption key.
- 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 using the RNCryptor library.
Implementations:
- iOS: open source one.
- 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, both derived from the password used for authentication or encryption passphrase. Salts are generated on the sync server.
The encryption and HMAC keys are stored on the device, 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 localStorage as a fallback.
Shared data encryption
For team shared data, Termius uses hybrid encryption.
- Each team member and the team owner has a key pair used for personal data encryption.
- The team owner generates a team encryption key.
- The team owner exchanges the team encryption key with each team member by encrypting the key using a team member's public key and utilizes the team owner's private key for creating MAC.
- A team member decrypts the exchanged team encryption key with the private key and uses the team owner's public key to verify the MAC.
The encryption of shared data and personal data uses the same schema because:
- It allows restoring an account when the password or encryption passphrase is lost.
- It prevents re-encryption of the whole database on password / encryption passphrase change. The Termius team's experience shows that it is an error-prone action.
Technical details
Termius uses Libsodium for encrypting team shared data and personal data that has been migrated to the 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 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 localStorage as a fallback.
Please, email us at security@termius.com, if you have any security concerns.
Add comment
Please sign in to leave a comment.