MC proxy

🧩 Anatomie MeshCore paketu (Typ 0x88)

Paket 0x88 není jen „zpráva“, je to Transportní rámec. V MeshCore světě se mu říká MeshPacket a jeho struktura vypadá přibližně takto:

Část paketuDélka (bajty)Popis
BLE Type1 (0x88)Identifikátor, že jde o MeshCore data pro rádio.
Flags / Hop info1–2Informace o tom, kolikrát paket skočil (TTL) a priority.
Sender ID4–6Zkrácený hash veřejného klíče odesílatele.
Recipient ID4–6Zkrácený hash příjemce (nebo 0xFF pro broadcast).
Payload Length1Kolik bajtů následuje.
Encrypted PayloadZbytekZde je ten zakopaný pes.

Proč naše dešifrování selhává?

Pokud se podíváme na vaše délky (58, 59, 163), vidíme dva problémy:

  1. Variabilní délka hlavičky: Podle toho, jestli zpráva jde přímo (Direct) nebo přes kanál (Flood), se mění počet bajtů před samotným šifrovaným obsahem.
  2. Protobuf obálka: MeshCore nepoužívá AES na čistý text. On vezme text, zabalí ho do Protobuf objektu Data, ten pak zašifruje, a tento zašifrovaný blok pak vloží do dalšího Protobuf objektu MeshPacket.
  3. Zarovnání AES: AES-ECB vyžaduje bloky o velikosti přesně 16 bajtů. Pokud nám v datech chybí byť jen jeden bajt hlavičky, dešifrování sice proběhne, ale výsledek bude totální náhodný šum (garbage), ve kterém náš dekodér nenajde značku 0x08.

🔍 Co je v dešifrovaných datech (vnitřní vrstva)

Když se nám podaří AES prolomit, nezískáme hned „Ahoj“. Získáme binární data, která musíme znovu parsovat:

Jak postupovat dál?

Abychom pohnuli s dešifrováním, potřebujeme zjistit přesný index, kde začínají šifrovaná data. Máte v té složce meshcore_proxy také soubor s názvem mesh.py nebo něco, co obsahuje definice MeshPacket?

Pokud ne, zkusíme jednu věc – podívat se na ty vaše HEX výpisy z minula. Všimněte si:

88 1b 94 1d 02 36 0f 7a 9b 04 88 4a 0f...

88 2d c9 1d 03 36 0f a8 7a 9b 04 88 4a 0f...

Tyto dva pakety jsou skoro stejné. Sekvence 36 0f a 7a 9b 04 88 4a 0f se opakuje. To jsou pravděpodobně ID odesílatele a kanálu.


🧩 Struktura paketu typu 0x88 (Mesh Packet Event)

Když rádio přijme zprávu z terénu, pošle ji přes BLE s hlavičkou 0x88. Na rozdíl od běžných zpráv (typ 0x08), které rádio samo dešifruje, paket 0x88 je čistý binární dump z éteru.

Zde je rozbor vašich dat (např. ten o délce 74 bajtů): 88 | 1b 94 | 1d | 02 | 36 0f 7a 9b 04 88 4a 0f ...

  1. Typ (1B): 0x88 – Oznamuje Pythonu: „Tady je syrový paket, který jsem právě zachytil na rádiu“.
  2. Packet ID / Checksum (2B): 1b 94 – Unikátní identifikátor paketu pro potvrzení (ACK).
  3. Flags (1B): 0x1d – Informace o prioritě a typu (zda je to Flood, Direct, atd.).
  4. Hop Limit (1B): 0x02 – Kolikrát ještě může zpráva v síti „skočit“.
  5. Data (Zbytek): Samotný MeshPacket, který je zakódovaný pomocí Protocol Buffers (Protobuf).

🔒 Kde je to šifrování?

Tady je ten největší rozdíl oproti vašim předchozím pokusům: Šifrování není na začátku celého paketu, ale až uvnitř Protobuf struktury.

V aktuální verzi MeshCore vypadá cesta k textu takto:

  1. Python přijme 0x88.
  2. Odřízne prvních 5 bajtů hlavičky.
  3. Zbytek musí rozbalit jako Protobuf zprávu MeshPacket.
  4. V tom MeshPacketu najde pole encrypted_payload.
  5. Až toto pole (a nic jiného) dešifruje pomocí AES-128-ECB klíčem kanálu.
  6. Výsledek dešifrování je další Protobuf zpráva (tzv. Data), která konečně obsahuje pole text.

Analýza tvých RAW dat

Když se podíváme na ten dlouhý paket (133B), vidíme tam tohle: ... 00 43 45 42 4f 5f 52 50 54 5f 30 33 20 f0 9f a7 aa To v překladu znamená: CEBO_RPT_03 🔌.

Co nám to říká?

  1. Není to všechno šifrované: MeshCore (podobně jako Meshtastic) posílá „NodeInfo“ (jméno uzlu, stav baterie, ikonu) nešifrovaně, aby se uzly v síti viděly.
  2. Struktura hlavičky: Pakety začínají bajtem 0x88 nebo 0x8a.
    • Prvních cca 12 bajtů je Mesh Header (ID odesílatele, ID příjemce, ID paketu, Hop Limit).
    • Zbytek je Payload (Protobuf struktura).
  3. Šifrování: Skutečné zprávy (Data) jsou šifrovány AES-CTR. Problém tvého předchozího kódu byl v tom, že jsi zkoušel náhodné offsety, ale pro CTR režim musíš mít přesný Nonce.

Jak se v MeshCore tvoří Nonce?

V AES-CTR režimu se pro každý paket generuje unikátní 16bajtový inicializační vektor (Nonce). Pokud ho netrefíš přesně na bajt, výsledek bude vždycky „rozsypaný čaj“, i když máš správný klíč k danému kanálu.

V MeshCore se Nonce obvykle skládá z: