πŸ“± Two-Factor Authentication (2FA) client for Android + Wear OS

RAW Doc

Doc/BACKUP FORMAT

Backup File Format

If you are migrating your authenticators from another app, you can create your own Stratum backup file to quickly import all your data. An unencrypted backup file is written in JSON and has the following format:

text
{
    "Authenticators": [
        {
            "Type": 2,
            "Icon": "google",
            "Issuer": "Google",
            "Username": "[email protected]",
            "Secret": "SECRETKEY123ABCD",
            "Pin": null,
            "Algorithm": 0,
            "Digits": 6,
            "Period": 30,
            "Counter": 0,
            "Ranking": 0,
            "CopyCount": 10
        }
    ],
    "Categories": [
        {
            "Id": "a8323a2a",
            "Name": "Web",
            "Ranking": 0
        }
    ],
    "AuthenticatorCategories": [
        {
            "CategoryId": "a8323a2a",
            "AuthenticatorSecret": "SECRETKEY123ABCD",
            "Ranking": 0
        }
    ],
    "CustomIcons": [
        {
            "Id": ".....",
            "Data": "....."
        }
    ]
}

Authenticator

  • For HOTP and TOTP, the authenticator secret key must be an uppercase base-32 string with no spaces. It can also contain '=' as a padding character.

  • In the case of Mobile-OTP and Yandex codes, the pin field must be set. Otherwise, it can be null.

  • Type: 1 = HOTP, 2 = TOTP, 3 = Mobile-Otp, 4 = Steam, 5 = Yandex

  • Algorithm (applies to HOTP and TOTP): 0 = SHA-1, 1 = SHA-256, 2 = SHA-512

  • Authenticators are ordered by their ranking, unless they're placed into categories where they will be ordered by the AuthenticatorCategory ranking instead.

  • Digits must be between 6 and 8 for HOTP, between 6 and 10 for TOTP. This parameter is ignored for Steam, Mobile-Otp and Yandex.

  • Period must be > 0

  • The issuer must not be null or blank. The username can be null.

Category

  • The category Id is the first 8 characters of the SHA-1 hash of the name.

  • The category name must be unique.

AuthenticatorCategory

  • An AuthenticatorCategory simply binds Authenticators into Categories using both their primary keys (AuthenticatorSecret and CategoryId).

CustomIcon

  • If the icon field of an authenticator starts with '@' then it is an ID of a custom icon.

  • Custom icons have an ID (8 characters of SHA1 hash) and some data (bitmap encoded in base64).

Encrypted Backups

Strong

Stratum backups are encrypted using AES_GCM with no padding. The key is derived using Argon2id with the following parameters:

Parameter Value
Parallelism 4
Memory Size 64 MiB
Iterations 3

The file is structured as follows:

Section Size Value
Header 16 AUTHENTICATORPRO
Salt 16 .
IV 12 .
Payload . .
Tag 16 .

Legacy

Stratum backups are encrypted using AES_CBC_PKCS7. The key is derived using PBKDF2 with SHA1 over 64000 iterations.
The file is structured as follows:

Section Size Value
Header 16 AuthenticatorPro
Salt 20 .
IV 16 .
Payload . .

Decryption without the app

A Python tool can be used to decrypt your backups.

Backup Decryption Tool

First, install the required packages with pip.

text
pip install cryptography argon2-cffi

Run the Python script with your backup as a parameter. Optionally direct the output to a file.

text
python decrypt_backup.py backup.authpro > backup_decrypted.json

You will be prompted for the password, and once decrypted the output will be sent to the backup_decrypted.json file.


CONTRIBUTING

Contribution Guide

Translations πŸ’¬

Translations are now managed on Crowdin. Go to the Stratum Crowdin project to contribute. If your language is not available, please contact me and I will add it.

Icons ⏺️

If you'd like to contribute some icons, first check if there's any open issues from user requests.

Icon criteria:

Not every service needs an icon. To prevent the app having hundreds of icons from obscure and rarely used platforms, we limit what icons can be added. If a service doesn't meet the criteria we encourage the use of custom icons from within the app.

  • Platforms that use a 'Single Sign-On' should have the icon added for the sign-on account and not for the individual platforms. Eg: instead of a YouTube icon a Google icon would be needed, or instead of a Photoshop icon an Adobe icon should be used.
  • Web based platforms should be within Similarweb's top 200,000 global rank. Simply search for the site and see for yourself.
  • Mobile platforms should have at least 100k+ downloads on the Google Play Store.
  • If the service is not web based or on the Play Store it will have to be reviewed individually, in which case it's best to just submit a request as a issue.

How to add an icon:

To add an icon to the project the procedure is as follows:

  • Fork the repo

  • Find a high-quality icon for the service you want to add. Try searching online for '{service_name} brand' - generally, many services offer high-res versions of their logos and icons for press and media.

    • Avoid icons made by 3rd parties with different styles from the original
    • Prefer flat icons instead of complex ones
    • Avoid text
    • Avoid unnecessary frames and backgrounds
  • Save the icon as a square 128x128 png

    • The icon must fill as much space as possible
    • The background should be transparent
  • Name the icon as lowercase with spaces and special characters removed. Eg: My Service -> myservice

  • Place the file in the "icons" directory

  • If the icon requires a dark theme variant, repeat the process and append "_dark" to the name.

  • Commit your changes

  • Create a pull request with your changes

Code / Features βš™οΈ

Before submitting any code, please open an issue to discuss if the feature is relevant.

AI pull requests

Any pull requests containing code generated primarily by a LLM will be closed. This applies if the author's contribution can be summed up as merely providing a prompt to a LLM without any real understanding of what they're doing.