Vos paquets ne regardent personne d'autre que vous.
Le Wi-Fi est un médium partagé. Cafés, hôtels, dortoirs, LAN parties. Quiconque sur le même réseau peut voir votre trafic. Dish a été conçu en gardant cela à l'esprit.
Modèle de menace
Dish est conçu pour rester sûr sur des réseaux dont vous ne pouvez pas pleinement vous fier :
- Un colocataire ou un voisin sur le même Wi-Fi ne devrait pas pouvoir injecter des entrées de manette dans votre jeu.
- Quelqu'un faisant tourner
tcpdumpsur le routeur ne devrait pas voir ce à quoi vous jouez ou comment vous jouez. - Un paquet capturé ne devrait pas être rejouable une heure plus tard.
- L'appairage doit échouer en mode fermé. Jamais de repli silencieux vers du texte en clair.
- La surface de configuration ne devrait pas être joignable depuis le LAN. Seul le chemin chiffré de la manette l'est.
Appairage
La première fois que vous connectez Dish à Satellite, Satellite affiche un PIN à 4 chiffres sur votre PC de jeu. Le PIN vit cinq minutes, puis expire. Vous le tapez dans Dish sur votre téléphone, portable ou autre appareil client.
L'appairage se fait en HTTPS sur le port 9443, sur un certificat auto-signé que Satellite génère localement. Le transport protège contre les écouteurs passifs ; le PIN protège contre quiconque tenterait de tromper Satellite pour qu'il lui fasse confiance. Le client envoie une clé publique X25519 de 32 octets, Satellite calcule le secret partagé avec crypto_scalarmult, et à partir de là les deux extrémités détiennent une clé symétrique de 256 bits dérivée sans jamais l'envoyer sur le fil. Le PIN lui-même est détruit une fois l'appairage terminé.
La clé partagée est stockée localement aux deux extrémités et sert à authentifier chaque reconnexion ultérieure. Côté Satellite elle vit dans le répertoire de configuration par utilisateur de votre plateforme, protégée en mode à votre compte (Windows DPAPI en V1) ; côté client Android elle vit dans les SharedPreferences privées de l'appli, isolées par Android à l'appli Dish et exclues de la sauvegarde cloud et du transfert d'appareil. Aucune clé ne quitte jamais l'un ou l'autre appareil.
AEAD par paquet
Chaque paquet de manette (entrée, battement de cœur, ajout de manette, vibrations, mouvement, batterie, pavé tactile, barre lumineuse) est scellé avec ChaCha20-Poly1305 (IETF), le même AEAD que TLS 1.3, WireGuard et SSH utilisent. ChaCha20 est rapide et à temps constant sur tous les CPU qui nous importent, dont l'ARMv8 d'Android et Apple Silicon.
Le format binaire est petit et rigide : jeton de session 4 octets, compteur 4 octets, texte chiffré, tag d'authentification Poly1305 16 octets. Le jeton sert aussi de données authentifiées supplémentaires (AAD), donc l'échanger dans un paquet rejoué provoque l'échec de la vérification. Le nonce est le compteur complété de zéros à 12 octets. Aucune réutilisation de nonce n'est possible sans renouveler la session.
Protection contre le rejeu
Satellite stocke le plus haut compteur qu'il a accepté sur chaque connexion. Tout paquet dont le compteur est inférieur ou égal à cette ligne haute est jeté avant même d'atteindre le backend de manette. Le texte chiffré capturé hier, ou même il y a une seconde, ne peut pas être rejoué pour déclencher une pression de bouton.
Ce dont vous n'avez pas à vous soucier
- Écoute clandestine. Personne sur le LAN n'apprend quels boutons vous avez pressés.
- Usurpation. Sans la clé de session, aucun attaquant ne peut injecter une pression sur « B », même s'il connaît votre IP.
- Rejeu. Le paquet « tir » d'hier ne tirera pas aujourd'hui. Pas plus que le battement de cœur ou le paquet d'appairage d'hier.
- Rétrogradation. Pas de repli en clair. Si la vérification cryptographique échoue, le paquet meurt en silence.
- Altération de la configuration à distance. L'API d'administration (
localhost:9877) se lie uniquement à127.0.0.1. L'API HTTPS face au LAN sur 9443 n'expose que les endpoints d'appairage et de session, tous protégés par un identifiant d'appareil appairé.
Zéro analyse, zéro pub
Dish et Satellite ne collectent aucune donnée d'usage, aucun identifiant, aucune analyse, aucun identifiant publicitaire. Le seul flux sortant touché par TinkerNorth sur Dish pour Android est Firebase Crashlytics, optionnel, pour les rapports de plantage et d'ANR : stack trace, modèle d'appareil, UUID d'installation, et c'est tout. Jamais les entrées de manette, jamais les IP de Satellite, jamais les SSID Wi-Fi. Une option d'opt-out d'un seul geste vit dans les Paramètres de l'appli sous Diagnostics, respectée avant qu'un plantage puisse être envoyé au prochain démarrage. Satellite lui-même est livré sans aucun SDK de rapport de plantage. La portée complète est sur la politique de confidentialité de Dish pour Android.
Nous n'exploitons pas de système de compte. Il n'y a pas de cloud. Rien à pirater puisqu'il n'y a rien sur un serveur à fuiter.
Chaîne d'approvisionnement auditable
Chaque version étiquetée est livrée avec :
- Un fichier de somme SHA-256 pour chaque artefact, signé sans clé via
cosignet l'identité OIDC du workflow de release GitHub Actions. - Une attestation de provenance SLSA Level 3 prouvant que l'artefact a été construit à partir du commit étiqueté dans la CI.
- Un nomenclature logicielle aux formats SPDX et CycloneDX, pour que vous puissiez auditer chaque dépendance transitive.
La recette verify-blob vit dans SECURITY.md dans le dépôt Satellite. Si un téléchargement ne correspond pas à la somme publiée, ne l'installez pas.
Open source et auditable
Chaque ligne de code touchant à la cryptographie vit dans un dépôt public. Satellite utilise libsodium ; Dish pour Android utilise libsodium-stable compilée via le NDK et le standard Conscrypt d'Android pour le transport d'appairage HTTPS. Aucune cryptographie maison. Aucun « on a écrit notre propre ChaCha ».
Distribué sous la GNU Lesser General Public License v3.0 or later. Vous avez trouvé quelque chose qui cloche ? SECURITY.md dans le dépôt Satellite contient notre politique de divulgation.