mirror of
https://github.com/gadgethd/ukmesh.git
synced 2026-10-15 18:50:05 +00:00
* docs: add C5a mission handoff * security: classify channel keys and baseline reviewed findings * security: revalidate MQTT auth and revoke owner sessions * test(ops): cover concurrent newuser grant updates * fix(ops): preserve executable newuser test * fix(ops): cover partial newuser rollback failures * fix(owner): preserve password whitespace during login * docs: add C5c mission handoff * test(cache): drop stale authCache policy entry (cache removed by auth revalidation) * docs: keep HANDOFF on current mission --------- Co-authored-by: gadgethd <111318106+gadgethd@users.noreply.github.com> Co-authored-by: hermes-gadget <284726080+hermes-gadget@users.noreply.github.com>
72 lines
3.3 KiB
Markdown
72 lines
3.3 KiB
Markdown
# MeshCore channel decryption
|
|
|
|
How the UK Mesh site decrypts group-text (packet type 5) traffic live, and
|
|
how historical traffic was retroactively decrypted.
|
|
|
|
## Key store
|
|
|
|
- `backend/src/mqtt/channelRegistry.ts` is the single source of truth:
|
|
- `PUBLIC_CHANNELS` — 41 recovered/community-known values intentionally
|
|
classified as public and baked into the image. Each was validated against
|
|
real human-readable UK Mesh group text.
|
|
- `buildCombinedKeyStore()` — merges baked defaults with
|
|
`MESHCORE_CHANNEL_SECRETS` (managed environment configuration, with
|
|
comma-separated `name:hex` or bare hex entries; dedupes by secret).
|
|
Environment-supplied entries are classified as confidential; never commit
|
|
their values or copy them into `PUBLIC_CHANNELS`.
|
|
- `buildSummary()` / `identifyChannel()` — shared by ingest and offline
|
|
tools.
|
|
- The repo is **public**. `PUBLIC_CHANNELS` is the explicit source classification;
|
|
the scanner baseline in `.gitleaksignore` records exact historical
|
|
commit/path/rule/line fingerprints for reviewed public values, test fixtures,
|
|
and generated revision identifiers. New findings remain blocking by default.
|
|
- Reading env at startup only — after a change:
|
|
`docker compose -f docker-compose.yml -f docker-compose.live.yml up -d --no-deps --force-recreate backend`.
|
|
|
|
## Decryption format
|
|
|
|
GRP_TXT payload = `[channel hash 1B][MAC 2B][AES-128-ECB ciphertext]`.
|
|
Hashtag channel keys are derivable: `sha256("#name")[:16]`. The public
|
|
channel key (`8b3387e9c5cdea6ac9e5edbaa115cd72`, hash byte `11`) is published
|
|
in MeshCore docs. Other derivation schemes exist in the wild (sha1/md5
|
|
variants, direct ASCII passphrases).
|
|
|
|
## Stored decrypted data
|
|
|
|
- Live ingest stores decrypted content inline in `payload.decrypted`
|
|
(message/sender/timestamp/flags) and `_summary` =
|
|
`[ChannelName] sender: message`.
|
|
- Historical decryption lives in the `packet_decryptions` side table
|
|
(migration 035), filled by the backfill tool. The feed joins it with
|
|
`COALESCE(p.payload->>'_summary', pd.summary)`.
|
|
- ⛔ Never bulk-UPDATE the `packets` hypertable — TimescaleDB plans a seq-scan
|
|
over every chunk. INSERT into the side table instead.
|
|
|
|
## Backfill tool
|
|
|
|
`node dist/tools/backfillDecrypt.js` (run inside the backend container).
|
|
Two-phase keyset-paginated scan over `packets_hash_idx` (~1,250 hashes/s).
|
|
2026-08-06 run: 387,161 packets processed, 173,778 decrypted.
|
|
|
|
## Feed integration
|
|
|
|
- `GET /api/feed/messages?channel=<scope>&limit<=50` — up to 50 unique
|
|
historical messages per channel (90-day bound, dedup by packet hash).
|
|
- The feed sidebar lists every decrypted channel
|
|
(`MESSAGE_SCOPE_CHANNELS` in `frontend/src/pages/ukmesh/feedModel.ts`);
|
|
new channels need a frontend rebuild to appear as filters.
|
|
|
|
## Validation gate (Ben, 2026-08-06)
|
|
|
|
Never deploy a recovered key whose plaintext isn't verified USEFUL — sane
|
|
epoch timestamps + printable UTF-8 on a time-spread sample. 1-byte hash
|
|
buckets collide across channels (MAC pass rate can reach ~97% on junk);
|
|
always validate before `.env` deploy. Honest decrypt coverage measured at
|
|
**~43.5%** of the 90-day volume (raw hash-bucket sums overcount).
|
|
|
|
## Out-of-band keys
|
|
|
|
`~/ukmesh/meshcore-discord-bot/.env` holds `NORTHEAST_CHANNEL_SECRET`
|
|
(== #northeast) and `THENORF_CHANNEL_SECRET` (hash 8A) — the discord bot
|
|
forwards those channels. Check it before attacking new keys.
|