{"id":47765164,"url":"https://github.com/traceflight/tls-decryptor","last_synced_at":"2026-04-03T06:12:52.788Z","repository":{"id":346153857,"uuid":"1188710111","full_name":"traceflight/tls-decryptor","owner":"traceflight","description":"A Rust TLS decryption library (with private key) supporting TLS 1.2 and TLS 1.3 Application Data record decryption.","archived":false,"fork":false,"pushed_at":"2026-03-22T15:01:07.000Z","size":48,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-23T05:28:46.609Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/traceflight.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-22T13:32:22.000Z","updated_at":"2026-03-22T15:01:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/traceflight/tls-decryptor","commit_stats":null,"previous_names":["traceflight/tls-decryptor"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/traceflight/tls-decryptor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/traceflight%2Ftls-decryptor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/traceflight%2Ftls-decryptor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/traceflight%2Ftls-decryptor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/traceflight%2Ftls-decryptor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/traceflight","download_url":"https://codeload.github.com/traceflight/tls-decryptor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/traceflight%2Ftls-decryptor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31338489,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T04:42:29.251Z","status":"ssl_error","status_checked_at":"2026-04-03T04:42:12.667Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-03T06:12:50.366Z","updated_at":"2026-04-03T06:12:52.771Z","avatar_url":"https://github.com/traceflight.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TLS Decryptor\n\nA Rust TLS decryption library (with private key) supporting TLS 1.2 and TLS 1.3 Application Data record decryption.\n\n## Prerequisites\n\n**Important:** This library requires access to the private key to derive session keys and decrypt TLS traffic. Specifically:\n\n- **TLS 1.2 with RSA key exchange**: Requires the server's RSA private key to decrypt the Pre-Master Secret from the ClientKeyExchange message\n- **TLS 1.2 with ECDHE key exchange**: Requires the ECDHE private key to compute the shared secret\n- **TLS 1.3**: Requires the ECDHE private key to compute the shared secret\n\nWithout the corresponding private key, this library cannot derive the session keys needed for decryption.\n\n## Features\n\n- 🔐 Derive TLS session keys from private keys and handshake parameters\n- 📦 Decrypt individual TLS Application Data records using session keys\n- 🔧 Support for multiple cipher suites (AES-GCM, ChaCha20-Poly1305)\n- 🧩 Extensible cipher suite architecture\n- ✅ Comprehensive test coverage with test data verified by Python scripts\n\n## Dependencies\n\nThis project is built upon:\n\n- **[RustCrypto](https://github.com/rustcrypto/)** - Provides cryptographic algorithms used throughout the library\n- **[tls-parser](https://crates.io/crates/tls-parser) ([GitHub](https://github.com/rusticata/tls-parser))** - Provides TLS record parsing capabilities\n\n## Supported Cipher Suites\n\n### TLS 1.2\n| Cipher Suite Name | ID | Key Exchange | Encryption |\n|------------------|-----|--------------|------------|\n| TLS_RSA_WITH_AES_128_GCM_SHA256 | 0x009C | RSA | AES-128-GCM |\n| TLS_RSA_WITH_AES_256_GCM_SHA384 | 0x009D | RSA | AES-256-GCM |\n| TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 | 0xCCA8 | ECDHE | ChaCha20-Poly1305 |\n\n### TLS 1.3\n| Cipher Suite Name | ID | Encryption |\n|------------------|-----|------------|\n| TLS13_AES_128_GCM_SHA256 | 0x1301 | AES-128-GCM |\n| TLS13_AES_256_GCM_SHA384 | 0x1302 | AES-256-GCM |\n| TLS13_CHACHA20_POLY1305_SHA256 | 0x1303 | ChaCha20-Poly1305 |\n\n## Installation\n\nAdd the dependency to your `Cargo.toml`:\n\n```toml\n[dependencies]\ntls-decryptor = \"0.1.0\"\n```\n\n## Quick Start\n\n### TLS 1.2 RSA Key Exchange\n\n```rust\nuse tls_decryptor::{\n    TlsDecrypter, SessionKey, Direction,\n    key_derivation::derive_keys_tls12,\n    types::CipherSuite,\n};\n\nfn main() -\u003e Result\u003c(), tls_decryptor::DecryptError\u003e {\n    // 1. Decrypt Pre-Master Secret using private key\n    // Note: This requires an external RSA library (e.g., rsa crate)\n    // let private_key_pem = std::fs::read_to_string(\"server_key.pem\")?;\n    // let encrypted_pms = /* extracted from ClientKeyExchange message */;\n    // let pre_master_secret = /* decrypt using RSA private key */;\n    let pre_master_secret = /* Pre-Master Secret obtained from RSA decryption */;\n\n    // 2. Derive session keys\n    let client_random = /* extracted from ClientHello (32 bytes) */;\n    let server_random = /* extracted from ServerHello (32 bytes) */;\n    let cipher_suite = CipherSuite::TLS_RSA_WITH_AES_128_GCM_SHA256;\n\n    let session_key = derive_keys_tls12(\n        \u0026client_random,\n        \u0026server_random,\n        \u0026pre_master_secret,\n        cipher_suite,\n    )?;\n\n    // 3. Create decrypter and decrypt\n    let mut decrypter = TlsDecrypter::new(session_key)?;\n    let encrypted_record = /* TLS Application Data record */;\n    \n    let plaintext = decrypter.decrypt_application_data(\n        \u0026encrypted_record,\n        Direction::ServerToClient,\n    )?;\n\n    println!(\"Decrypted: {:?}\", String::from_utf8_lossy(\u0026plaintext));\n    \n    Ok(())\n}\n```\n\n### TLS 1.3 ECDHE Key Exchange\n\n```rust\nuse tls_decryptor::{\n    TlsDecrypter, Direction,\n    key_derivation::derive_keys_tls13,\n    types::CipherSuite,\n};\n\nfn main() -\u003e Result\u003c(), tls_decryptor::DecryptError\u003e {\n    // 1. Compute ECDHE shared secret\n    // Use util::compute_shared_secret_tls13 or compute manually\n    let shared_secret = /* ECDHE shared secret */;\n\n    // 2. Derive session keys\n    let cipher_suite = CipherSuite::TLS13_AES_128_GCM_SHA256;\n    let handshake_hash = /* hash of handshake messages */;\n\n    let session_key = derive_keys_tls13(\n        \u0026shared_secret,\n        cipher_suite,\n        \u0026handshake_hash,\n    )?;\n\n    // 3. Create decrypter and decrypt\n    let mut decrypter = TlsDecrypter::new(session_key)?;\n    let encrypted_record = /* TLS Application Data record */;\n    \n    let plaintext = decrypter.decrypt_application_data(\n        \u0026encrypted_record,\n        Direction::ClientToServer,\n    )?;\n\n    println!(\"Decrypted: {:?}\", String::from_utf8_lossy(\u0026plaintext));\n    \n    Ok(())\n}\n```\n\n### Decrypt with Known Session Keys\n\nIf you already have the session keys (e.g., exported from Wireshark or other tools), you can directly create a `SessionKey`:\n\n```rust\nuse tls_decryptor::{TlsDecrypter, SessionKey, Direction};\nuse tls_decryptor::types::TlsVersion;\nuse rustls::CipherSuite;\n\nfn main() -\u003e Result\u003c(), tls_decryptor::DecryptError\u003e {\n    // Directly create session key\n    let session_key = SessionKey::new(\n        TlsVersion::Tls13,\n        CipherSuite::TLS13_AES_128_GCM_SHA256,\n        vec![0u8; 16], // client_write_key\n        vec![0u8; 16], // server_write_key\n        vec![0u8; 12], // client_write_iv\n        vec![0u8; 12], // server_write_iv\n    );\n\n    let mut decrypter = TlsDecrypter::new(session_key)?;\n    \n    // Decrypt data\n    let encrypted_record = hex::decode(\"170303002c...\")?;\n    let plaintext = decrypter.decrypt_application_data(\n        \u0026encrypted_record,\n        Direction::ServerToClient,\n    )?;\n\n    Ok(())\n}\n```\n\n## API Reference\n\n### Core Types\n\n#### `TlsDecrypter`\nTLS record decrypter responsible for decrypting TLS Application Data records.\n\n```rust\n// Create decrypter\nlet decrypter = TlsDecrypter::new(session_key)?;\n\n// Create decrypter with initial sequence numbers\nlet decrypter = TlsDecrypter::with_sequence_numbers(\n    session_key,\n    client_to_server_seq,\n    server_to_client_seq,\n)?;\n\n// Decrypt Application Data record\nlet plaintext = decrypter.decrypt_application_data(\u0026encrypted_record, direction)?;\n\n// Manage sequence numbers\ndecrypter.set_sequence_number(Direction::ClientToServer, 100);\ndecrypter.reset_sequence_numbers();\n```\n\n#### `SessionKey`\nSession key material containing all keys required to decrypt TLS records.\n\n```rust\nlet session_key = SessionKey::new(\n    version,        // TlsVersion\n    cipher_suite,   // CipherSuite\n    client_write_key,\n    server_write_key,\n    client_write_iv,\n    server_write_iv,\n);\n```\n\n#### `Direction`\nData flow direction enum.\n\n```rust\nenum Direction {\n    ClientToServer,  // Client to server\n    ServerToClient,  // Server to client\n}\n```\n\n### Key Derivation Functions\n\n#### `derive_keys_tls12`\nTLS 1.2 key derivation function using PRF (Pseudo-Random Function).\n\n```rust\nuse tls_decryptor::types::CipherSuite;\n\npub fn derive_keys_tls12(\n    client_random: \u0026[u8; 32],\n    server_random: \u0026[u8; 32],\n    pre_master_secret: \u0026[u8],\n    cipher_suite: CipherSuite,\n) -\u003e Result\u003cSessionKey\u003e\n```\n\n#### `derive_keys_tls13`\nTLS 1.3 key derivation function using HKDF (HMAC-based Key Derivation Function).\n\n```rust\nuse tls_decryptor::types::CipherSuite;\n\npub fn derive_keys_tls13(\n    shared_secret: \u0026[u8],\n    cipher_suite: CipherSuite,\n    handshake_hash: \u0026[u8],\n) -\u003e Result\u003cSessionKey\u003e\n```\n\n## Architecture\n\n### Cipher Suite Architecture\n\nThe library uses an extensible cipher suite architecture:\n\n1. **[`CipherContext`](src/cipher/trait_def.rs)** - Trait defining the cipher suite interface\n2. **[`CipherRegistry`](src/cipher/registry.rs)** - Global registry (singleton pattern)\n3. **[`suites/`](src/cipher/suites/)** - Concrete suite implementations\n\nAdding a new cipher suite:\n1. Create a new file in `src/cipher/suites/`\n2. Implement the `CipherContext` trait\n3. Add `pub mod` declaration in [`cipher/suites/mod.rs`](src/cipher/suites/mod.rs)\n4. Register in [`cipher/registry.rs`](src/cipher/registry.rs) `register_builtins()`\n\n## Technical Details\n\n### TLS 1.2 Key Derivation\n\n```\nmaster_secret = PRF(pre_master_secret, \"master secret\", \n                    ClientHello.random + ServerHello.random)\n\nkey_block = PRF(master_secret, \"key expansion\",\n                ServerHello.random + ClientHello.random)\n\nkey_block = client_write_key | server_write_key | \n            client_write_IV | server_write_IV\n```\n\n### TLS 1.3 Key Derivation\n\n```\nhandshake_secret = HKDF-Extract(0, shared_secret)\nmaster_secret = HKDF-Extract(0, handshake_secret)\n\nclient_application_traffic_secret = \n    HKDF-Expand-Label(master_secret, \"c ap traffic\", handshake_hash)\n\nkey = HKDF-Expand-Label(traffic_secret, \"key\", \"\", key_length)\niv = HKDF-Expand-Label(traffic_secret, \"iv\", \"\", iv_length)\n```\n\n### AEAD Additional Data\n\nThe Additional Authenticated Data (AAD) used for AEAD decryption must be the 5-byte TLS record header:\n```\nAAD = content_type (1) || version (2) || length (2)\n```\n\n### Sequence Number Management\n\n- `TlsDecrypter` maintains sequence numbers for both directions internally\n- Each direction counts independently\n- Wraps around to 0 on overflow\n\n## Contributing\n\nIssues and Pull Requests are welcome!\n\n## Related Links\n\n- [RFC 5246 - TLS 1.2](https://tools.ietf.org/html/rfc5246)\n- [RFC 8446 - TLS 1.3](https://tools.ietf.org/html/rfc8446)\n- [rustls](https://github.com/rustls/rustls)\n\n## License\n\nThis project is licensed under either of\n\n * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n   http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license ([LICENSE-MIT](LICENSE-MIT) or\n   http://opensource.org/licenses/MIT)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftraceflight%2Ftls-decryptor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftraceflight%2Ftls-decryptor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftraceflight%2Ftls-decryptor/lists"}