Pure Rust parser for Telegram Desktop's tdata storage.
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.
- 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
mapfiles (account data). - Reads
AuthKey,UserId, andDcIdvalues. - Supports new (64-bit ID) and legacy tdata formats.
- Parses
- Interoperability:
- Produces
grammers_session::SessionDatavalues for import into agrammerssession storage.
- Produces
- Multi-account storage: Reads every account index present in the local key data.
Add this to your Cargo.toml:
[dependencies]
hermes-tdata = "0.2"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.
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(())
}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-keysOutput 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]
This library handles live authentication credentials.
- Never share your
tdatafolder, session data, auth keys, or output produced with a--show-*option. - Anyone with session data or an
AuthKeycan 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.
Debugoutput forAccount,TDesktop, andAuthKeyredacts paths, account identifiers, and key material.- Passcodes can be entered through a hidden prompt or stdin and are not retained by the parsed
TDesktopobject. - The crate performs no network requests.
- opentele (Python) - Protocol reference.
- tdesktop (C++) - The source of truth.
- grammers (Rust) - Session format compatibility.
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributions are welcome through issues and pull requests.