hermes-tdata 0.2.1

Pure Rust parser for Telegram Desktop tdata storage with grammers session conversion
Documentation

hermes-tdata

Pure Rust parser for Telegram Desktop's tdata storage.

Crates.io Documentation CI License

Parse Telegram Desktop's local tdata storage and convert authorized account data into grammers_session::SessionData. The crate reads local files only and does not include a network client.

[!CAUTION] Session data and authentication keys grant account access. Use this crate only with storage you own or are explicitly authorized to inspect, and treat every generated session as a credential.

Features

  • Pure Rust parser: No Qt, C++, or Python runtime dependency.
  • Local storage cryptography:
    • PBKDF2-SHA512 key derivation with custom parameters.
    • AES-256-IGE decryption through grammers-crypto.
    • MD5/SHA1 file integrity verification.
  • MTP parsing:
    • Parses key_data (local keys).
    • Parses map files (account data).
    • Reads AuthKey, UserId, and DcId values.
    • Supports new (64-bit ID) and legacy tdata formats.
  • Interoperability:
    • Produces grammers_session::SessionData values for import into a grammers session storage.
  • Multi-account storage: Reads every account index present in the local key data.

Installation

Add this to your Cargo.toml:

[dependencies]
hermes-tdata = "0.2"

Migrating from 0.1

Version 0.2 is a security-focused API rewrite. Import TDesktop from the crate root and use Account::to_grammers_session_data() as the credential-bearing handoff to a grammers session storage. The old to_session_string() API was removed rather than silently changing its serialized format.

Quick start

Convert tdata to grammers SessionData

use hermes_tdata::TDesktop;

fn main() -> Result<(), hermes_tdata::Error> {
    let tdata = TDesktop::from_default()?;

    println!("Found {} account(s)", tdata.accounts().len());

    // SessionData contains authentication credentials: never log or serialize it.
    for account in tdata.accounts() {
        let session_data = account.to_grammers_session_data();
        println!("SessionData prepared for DC {}", session_data.home_dc);
    }

    Ok(())
}

CLI utility

The repository includes a local inspection example. Credential output remains redacted unless an explicit --show-* flag is supplied.

# Clone and run
git clone https://github.com/Stranmor/hermes-tdata
cd hermes-tdata

# Run with default tdata path
cargo run --example cli

# Or specify a custom path
cargo run --example cli -- /path/to/tdata

# Prompt for a passcode without echoing it or storing it in shell history
cargo run --example cli -- --prompt-passcode

# For automation, pass it through stdin rather than a command-line argument
printf '%s\n' "$TDATA_PASSCODE" | cargo run --example cli -- --passcode-stdin

# Private paths, account identifiers, and auth keys are opt-in
cargo run --example cli -- --show-identifiers
cargo run --example cli -- --show-keys

Output example:

📂 Reading tdata from: [redacted; use --show-identifiers to reveal]
✅ Successfully loaded TDesktop storage!
   App Version: 6004001
   Passcode:    NO
   Accounts:    2

👤 Account #1 (Index 0)
   User ID:   [redacted; use --show-identifiers to reveal]
   DC ID:     2
   Grammers:  SessionData conversion available
   Auth Key:  [redacted; use --show-keys to reveal]

👤 Account #2 (Index 1)
   User ID:   [redacted; use --show-identifiers to reveal]
   DC ID:     2
   Grammers:  SessionData conversion available
   Auth Key:  [redacted; use --show-keys to reveal]

Security

This library handles live authentication credentials.

  • Never share your tdata folder, session data, auth keys, or output produced with a --show-* option.
  • Anyone with session data or an AuthKey can access the corresponding Telegram account without 2FA.
  • The CLI does not serialize or print session data and redacts paths, account identifiers, and auth keys by default.
  • Debug output for Account, TDesktop, and AuthKey redacts paths, account identifiers, and key material.
  • Passcodes can be entered through a hidden prompt or stdin and are not retained by the parsed TDesktop object.
  • The crate performs no network requests.

Acknowledgements

  • opentele (Python) - Protocol reference.
  • tdesktop (C++) - The source of truth.
  • grammers (Rust) - Session format compatibility.

License

Licensed under either of:

at your option.

Contributing

Contributions are welcome through issues and pull requests.