Livre blanc sur la sécurité de WIGGWIGG
Version : 1.1 (ébauche) · Date : 2026-07
WIGGWIGG est un produit de numéro de téléphone et d’identité axé sur la confidentialité. Ce document explique, en détail technique, comment on protège vos données : ce qu’on ne peut pas lire, ce qu’on peut lire et pourquoi, la cryptographie qu’on utilise, et où s’arrêtent nos garanties. Il s’adresse à un lecteur technique et sceptique.
Notre noyau cryptographique est ouvert sur github.com/WiggWiggDev/crypto (le
paquet @wiggwigg/crypto) : les primitives de dérivation de clé, de scellement et
de signature décrites ici sont vérifiables indépendamment de l’application fermée.
1. Résumé et position
- À connaissance nulle par conception. Votre mot de passe, vos entrées de coffre, vos identités, vos contacts et le contenu de vos messages sont chiffrés sur votre appareil avec des clés qu’on ne détient jamais. On ne peut pas les lire, et on ne peut pas être contraints de produire une clé qu’on n’a pas.
- Noyau ouvert, pas « code source ouvert ». On a ouvert le noyau cryptographique pour que vous puissiez vérifier comment les clés et les données sont protégées. Le reste de l’application (les surfaces opérationnelles et de lutte contre les abus) est fermé. On ne laisse jamais entendre le contraire.
- Les limites. Les numéros de téléphone, les adresses d’urgence (E911) et les métadonnées de routage sont lisibles par le serveur parce que le service téléphonique l’exige. On n’est pas chiffrés de bout en bout en transit (le réseau téléphonique est antérieur à cette possibilité). On n’a pas encore de confidentialité persistante ni de protection post-quantique. Ces limites sont énoncées aux sections 10 et 11.
- Auto-attesté aujourd’hui, audité de l’extérieur plus tard. Ce document s’appuie sur du code source ouvert et une politique publiée de divulgation des vulnérabilités. Un audit cryptographique et applicatif par un tiers est prévu ; on le publiera une fois terminé et on ne le revendiquera pas avant.
2. Modèle de menace et frontières de confiance
On conçoit contre un serveur pleinement malveillant, pas seulement honnête mais curieux : on suppose que notre infrastructure peut être compromise, saisie par ordonnance judiciaire, ou exploitée par quelqu’un qui ne devrait pas voir vos données, et qu’elle pourrait activement mentir à votre appareil plutôt que se contenter de regarder. Sous cette hypothèse, vos données à connaissance nulle restent illisibles parce que les clés vivent sur votre appareil. C’est le modèle de menace retenu par l’analyse cryptographique des gestionnaires de mots de passe publiée à USENIX Security 2026 (Zero Knowledge (About) Encryption, Scarlata et coll.), et c’est celui contre lequel on se mesure ; les résidus qu’il nous reste sous ce modèle sont énoncés à la section 10, pas passés sous silence.
| Frontière | Ce qu’on suppose | Ce qu’elle peut voir |
|---|---|---|
| Votre appareil | De confiance ; la crypto côté client s’y exécute | Tout ce que vous stockez (il détient vos clés) |
| Votre mot de passe / phrase de récupération | Secret, connu de vous seul | Rien ne quitte l’appareil |
| Serveurs WIGGWIGG | Peuvent être compromis, contraints, ou malveillants | Données opérationnelles chiffrées côté serveur (section 4) ; jamais les données à connaissance nulle |
| Base de données | Protégée par la sécurité au niveau des lignes et des déclencheurs | Du texte chiffré seulement, pour les données à connaissance nulle |
| Opérateur télécom (Telnyx) | Un « tuyau bête » qui n’apprend que ce que le routage exige | Métadonnées d’appels/SMS et contenu en transit (comme tout service téléphonique) |
| Processeurs de paiement (Stripe, Blockonomics) | Données minimisées | L’essentiel de la facturation par carte, ou une adresse Bitcoin et un montant ; jamais votre coffre ni vos identités |
On ne défend pas contre un appareil compromis (un logiciel malveillant sur votre propre appareil, ou une extension de navigateur malveillante), ni contre les métadonnées inhérentes au fait de passer un appel ou un SMS sur le réseau public. Voir la section 10.
3. Architecture cryptographique
Toutes les primitives ci-dessous proviennent de bibliothèques auditées
(@noble/curves,
@noble/hashes,
@scure/bip39). On n’écrit pas la nôtre.
- Dérivation de clé : votre mot de passe est étiré avec Argon2id (128 Mio de mémoire, 3 itérations). Elle est coûteuse en mémoire, ce qui la rend résistante au forçage par GPU et ASIC. Les paramètres sont identiques au bit près entre le web et le mobile, pour que vos clés concordent sur tous vos appareils.
- Indirection de la clé de coffre : la clé principale dérivée du mot de passe enveloppe une clé de coffre distincte, propre au compte, et vos données sont chiffrées sous la clé de coffre. Changer votre mot de passe ré-enveloppe la clé de coffre seulement ; ça ne re-chiffre jamais vos données.
- Chiffrement symétrique : AES-256-GCM (authentifié) pour les entrées de coffre, les identités, les contacts, le contenu des messages et les champs opérationnels côté serveur.
- Scellement par clé publique : le contenu des messages entrants est chiffré avec AES-256-GCM sous une clé à usage unique, elle-même scellée à la clé publique X25519 de votre appareil (X25519-ECDH, HKDF-SHA256, XChaCha20-Poly1305 : un coffre scellé de style libsodium). Si votre appareil n’a pas encore déposé de clé X25519, la clé de session est plutôt enveloppée en RSA-2048-OAEP, le schéma hérité ; chaque blob enregistre lequel a servi. Les deux sont à connaissance nulle (section 5), et le retrait de RSA figure à la feuille de route (section 11).
- Authentification : prouver que vous connaissez votre mot de passe sans le révéler (section 6).
- Séparation des clés : chaque clé dérivée reçoit sa propre étiquette de
domaine — HKDF-SHA256 sous une chaîne
infodistincte, ou HMAC-SHA256 sur une étiquette distincte — donc compromettre l’une n’en livre jamais une autre. Deux familles ne viennent délibérément pas de la clé principale : la clé de coffre est aléatoire et seulement enveloppée par elle, et les clés de récupération viennent de votre phrase BIP39 (section 7). - Agilité cryptographique : chaque schéma porte une version, pour qu’on puisse faire pivoter une primitive sans casser les données stockées. C’est ainsi que la mise à niveau post-quantique de la section 11 arrive sans réécriture.
4. Classification des données
Ce qui est, ou n’est pas, à connaissance nulle :
| Niveau | Données | Qui peut les lire |
|---|---|---|
| Connaissance nulle | Identités, entrées de coffre, contacts, contenu des SMS/MMS/messagerie vocale (par défaut), la graine du marqueur anti-hameçonnage (phrase/couleurs/avatar) | Votre appareil seulement |
| Chiffré côté serveur | Numéros de téléphone (routage), adresses E911 (répartition d’urgence), identifiants SIP, métadonnées de facturation, coût et métadonnées d’opérateur des appels/SMS | Le serveur peut déchiffrer (requis pour fonctionner) |
| Index aveugle | Recherches d’égalité (p. ex. par numéro) sans stocker le texte en clair | Le serveur compare un HMAC à clé, pas la valeur |
| Texte en clair | Identifiant de compte (un nom d’utilisateur public), horodatages, clés primaires et étrangères, is_admin | Quiconque a accès à la base (non sensible) |
Les exceptions : les numéros de téléphone et les adresses E911 sont lisibles par le serveur parce que le réseau doit router vos appels et que les services d’urgence doivent vous localiser. Le contenu de la messagerie vocale est à connaissance nulle sauf si vous activez l’écoute par téléphone, qui conserve une copie lisible par le serveur pour que vous puissiez écouter votre messagerie en appelant. Vos contacts sont à connaissance nulle sauf si vous activez « Reconnaissance des contacts lors des appels » (désactivée par défaut), qui conserve une empreinte à clé du numéro de chaque contact afin de reconnaître un appelant connu lors d’un appel entrant — ce qui rend ces numéros récupérables par nos serveurs tant que c’est activé. Le désactiver efface ces empreintes et rétablit la connaissance nulle. Ce sont des compromis assumés et optionnels pour un service téléphonique fonctionnel, pas des trous dans la connaissance nulle.
Les champs chiffrés côté serveur sont liés à leur contexte (par exemple, une adresse E911 est cryptographiquement liée à son propriétaire) pour qu’un texte chiffré ne puisse pas être déplacé d’un enregistrement à l’autre. Étendre ce lien à chaque champ serveur, ainsi qu’une dérivation de clé par utilisateur, figure à notre feuille de route publiée.
5. Communications : « aveugle au serveur », pas à confidentialité persistante
Chaque SMS, MMS ou message vocal entrant est scellé à la clé publique de votre appareil (X25519, ou le repli RSA-2048 de la section 3 si votre appareil n’a pas encore de clé X25519). Sur le chemin X25519, on génère une paire de clés d’expéditeur, on l’utilise une seule fois et on la détruit dès que le message est stocké ; le repli RSA, lui, chiffre directement vers votre clé publique, donc il n’y a aucune clé d’expéditeur au départ. Dans les deux cas, le résultat est le même : on ne conserve aucune clé capable de lire vos messages : ni au repos, ni plus tard, ni sous un mandat qui nous vise. On peut être contraints de produire les octets chiffrés ; on ne peut pas être contraints de produire une clé qu’on n’a pas.
Ce que ce n’est pas : ce n’est pas de la confidentialité persistante. Vos messages sont scellés à la clé à long terme de votre appareil, soit la même clé que votre appareil utilise pour relire votre historique sur un nouvel appareil. Si votre clé privée était compromise, votre historique stocké pourrait être déchiffré. On optimise pour l’aveuglement au serveur (un serveur ou un mandat ne peut pas lire votre contenu), qui est la propriété atteignable et utile pour un historique de messages stocké et relisible. La vraie confidentialité persistante entre en conflit avec un historique multi-appareils et n’est pas une chose qu’on revendique. Le durcissement post-quantique de ce sceau figure à notre feuille de route (section 11).
Le transit sur le réseau opérateur (SS7/SIP) est visible par les opérateurs comme tout service téléphonique. Pour un chiffrement de bout en bout en transit, utilisez Signal ou WhatsApp avec votre numéro WIGGWIGG.
6. Authentification
Votre mot de passe ne quitte jamais votre appareil. Aujourd’hui, votre appareil dérive la clé principale (Argon2id) et en calcule une preuve HMAC-SHA256. Le serveur ne stocke qu’un haché de cette preuve et le compare à la connexion. Le serveur ne voit jamais votre mot de passe, et une clé principale dérivée par Argon2id rend la preuve coûteuse à falsifier.
On migre la connexion vers un schéma défi-réponse Ed25519 où le serveur ne stocke qu’une clé publique et où vous prouvez la possession en signant un défi serveur à usage unique de 60 secondes, pour qu’une fuite du vérificateur en base ne puisse pas être rejouée pour se connecter. C’est construit et en cours de déploiement. On ne revendiquera pas la propriété plus forte « une fuite de base ne peut pas authentifier » tant que le vérificateur hérité n’est pas entièrement retiré.
Authentification à plusieurs facteurs : WebAuthn/clés d’accès (résistantes à l’hameçonnage) et TOTP. Anti-hameçonnage : avant que vous tapiez votre mot de passe complet, le site se prouve à vous avec un marqueur propre au compte (phrase, couleurs, avatar, audio optionnel) rendu sur votre appareil à partir d’une graine qu’on ne stocke que chiffrée. La graine est scellée sous une clé dérivée des premiers caractères de votre mot de passe — les mêmes qui déclenchent l’affichage (vérification partielle HMAC-SHA256) — de sorte que le serveur ne détient jamais de marqueur qu’il pourrait rendre, et qu’une fuite de la base de données seule ne peut pas forger votre marqueur sans forcer ces caractères contre la fonction de dérivation de clé. (La protection est bornée par cette faible entropie de quelques caractères, non incassable : elle déjoue la contrefaçon de masse à partir d’une base de données volée, le scénario réellement exploité après une brèche.)
7. Récupération de compte
La récupération utilise une phrase BIP39 de 24 mots (256 bits d’entropie) que vous détenez et qu’on ne voit jamais. Votre appareil en dérive deux clés distinctes, chacune sous sa propre étiquette de domaine : une clé X25519, à laquelle votre matériel de clé est scellé, et une clé de signature Ed25519, qui sert à prouver la possession de la phrase. On ne stocke que des clés publiques et un blob scellé qu’on ne peut pas ouvrir.
Ce blob scelle votre clé de coffre, pas votre clé principale. La distinction compte : la clé de coffre ne change pas quand vous changez de mot de passe, donc l’enveloppe de récupération n’a jamais à être re-scellée automatiquement. Un re-scellement automatique serait exactement la prise qu’un serveur malveillant chercherait, en substituant sa propre clé de récupération pour se rendre capable d’ouvrir l’enveloppe ; en scellant une clé stable, cette prise n’existe pas. Un changement de mot de passe lancé depuis une récupération est autorisé par une signature Ed25519 de votre phrase sur un défi serveur à usage unique, et votre appareil vérifie que la clé récupérée déchiffre bien vos données avant de re-chiffrer quoi que ce soit.
La clé de récupération de confiance est en outre épinglée dans vos préférences chiffrées, que le serveur ne peut pas lire : si la clé qu’il présente ne correspond pas à celle que votre appareil a épinglée, l’opération s’arrête et vous demande la confirmation de votre phrase, au lieu de sceller à l’aveugle sous une clé fournie par le serveur.
Si vous perdez à la fois votre mot de passe et votre phrase de récupération, vos données à connaissance nulle sont irrécupérables par conception : on ne peut pas les déchiffrer pour vous. Une réinitialisation assistée par un administrateur peut rétablir l’accès à votre compte (numéros de téléphone, facturation) mais seulement avec votre confirmation explicite et distincte, et elle ne récupère pas les données à connaissance nulle.
8. Gestion et rotation des clés
Les clés côté serveur (la clé de champ opérationnel, la clé d’index aveugle, la graine de métadonnées par utilisateur) vivent dans un coffre de secrets géré sous forme d’anneau versionné, validé au démarrage. Chaque schéma (KDF, clé de coffre, sceau asymétrique, clé serveur) porte une colonne de version, conçue pour une rotation sans interruption : les nouvelles écritures utilisent la version courante, et les lecteurs s’aiguillent sur la version stockée. Les colonnes porteuses de matériel cryptographique sont protégées par des déclencheurs de base de données qui refusent de les mettre à nul en silence.
En pratique, une rotation complète de la clé serveur se fait aujourd’hui en fenêtre de maintenance plutôt qu’à chaud : les deux versions cohabitent dans l’anneau, donc tout se déchiffre pendant la transition, et l’ancienne version n’est retirée qu’après une vérification qui refuse de la lâcher tant qu’une seule ligne en dépend encore. On décrit ici le mécanisme, pas une opération de routine, et on ne revendiquera la rotation à chaud qu’une fois qu’elle sera réellement exercée de bout en bout.
9. Sécurité de l’application et de l’infrastructure
- Sécurité au niveau des lignes : la base de données l’impose elle-même sur les
tables qui portent les données des comptes (avec
FORCE ROW LEVEL SECURITY, une fonction de contexte obligatoire qui lève une erreur au lieu de retourner des lignes en silence, et un garde-fou d’intégration continue). Elle refuse de remettre à un compte les lignes d’un autre ; l’extension aux dernières tables héritées est en cours. - Transport : TLS partout ; en-têtes de sécurité (CSP/HSTS) ; CSRF défendue par des témoins SameSite et une liste blanche d’origine stricte.
- Réseau : isolation par VPC et NAT par VPC comme défense en profondeur délibérée.
- Chiffrement au repos : la base de données, la cache et le stockage objet sont chiffrés avec des clés gérées (AWS KMS), sous le chiffrement applicatif et à connaissance nulle ci-dessus.
- Défense en profondeur : un pare-feu applicatif géré protège la bordure publique, avec détection de menaces en continu, journalisation d’audit du plan de contrôle, journaux de flux VPC, et sauvegardes chiffrées et versionnées.
- L’observabilité est pseudonyme par défaut : aucune adresse IP brute n’est conservée nulle part. Les journaux d’audit administrateur et de sécurité la hachent sous un secret serveur, qu’une fuite de la base seule ne permet pas d’inverser. Les autres empreintes d’IP sont salées par compte et par jour, mais sans secret : l’inversion en masse est bloquée, alors que quelqu’un qui détient la base pourrait encore retrouver une adresse visée. On étend le secret à celles-là. La télémétrie est conçue pour ne porter aucune identité d’utilisateur, et les métadonnées opérationnelles sont conservées 90 jours.
- On ne conserve pas votre agent utilisateur. La chaîne complète que votre navigateur envoie est une empreinte à faible entropie : la hacher la masque sans la supprimer. On la réduit dès la collecte à une étiquette grossière tirée d’une liste blanche fixe de 49 valeurs, comme « Chrome / macOS » : sans version, sans modèle d’appareil, sans clé. Ce qui pourrait vous distinguer est jeté avant d’être écrit. C’est de la minimisation des données, pas de l’anonymisation : l’étiquette reste sur une ligne qui porte votre identifiant de compte.
- Minimisation des données des fournisseurs : l’opérateur n’apprend que ce que le routage exige ; le processeur de cartes (Stripe) reçoit des identifiants opaques et des libellés génériques, et le processeur Bitcoin (Blockonomics) ne voit qu’une adresse de paiement et un montant. On ne les interroge jamais à votre sujet.
10. Limites et non-objectifs
On les énonce clairement :
- Appareil compromis. Un logiciel malveillant ou une extension malveillante sur votre appareil peut lire vos données après que vous l’avez déverrouillé. Le chiffrement côté client ne peut pas défendre un client compromis.
- Aucune confidentialité persistante sur les messages stockés (section 5).
- Intégrité de l’ensemble du coffre. Chaque entrée est scellée à sa propre identité, donc un serveur ne peut ni la lire, ni la déplacer vers un autre champ ou un autre compte. Ça ne prouve pas que l’ensemble qu’on vous renvoie est complet : un serveur malveillant pourrait omettre une entrée, en restituer une version antérieure, ou en changer l’ordre, sans que votre appareil puisse aujourd’hui le détecter. Tous les coffres à connaissance nulle sans état côté client partagent ce résidu. Le manifeste de la section 11 est notre réponse : écrit et validé, mais pas encore actif, et on ne le revendiquera pas avant.
- L’épinglage de la récupération ne couvre pas encore la clé de signature de récupération (section 7) : un serveur qui la substituerait provoquerait un déni de service au moment de la récupération, pas une lecture de vos données.
- Aucune protection post-quantique pour l’instant (section 11) : un adversaire quantique futur pourrait déchiffrer les données scellées en X25519 d’aujourd’hui (« récolter maintenant, déchiffrer plus tard »).
- Les métadonnées du service téléphonique (qui a appelé qui, quand, combien de temps) sont inhérentes au réseau public et visibles par les opérateurs. On les minimise et les conserve 90 jours, mais on ne peut pas les rendre privées.
- Les données opérationnelles lisibles par le serveur (numéros, E911, facturation) ne sont pas à connaissance nulle (section 4), car elles sont requises pour fonctionner.
- L’authentification est en pleine migration (section 6), donc la revendication la plus forte attend le retrait du vérificateur hérité.
11. Feuille de route
- Post-quantique (la vedette) : enveloppement de clé hybride X25519 + ML-KEM-768 pour le sceau des messages et l’enveloppe de récupération, pour qu’un attaquant doive briser les deux. Ça répond directement au « récolter maintenant, déchiffrer plus tard » pour les données stockées à long terme.
- Authentification : compléter le déploiement du défi-réponse Ed25519 et retirer le vérificateur hérité, puis évaluer un PAKE asymétrique (OPAQUE).
- Intégrité de l’ensemble du coffre : un manifeste authentifié sous votre clé de coffre, soit la liste chiffrée de vos entrées avec un compteur anti-retour en arrière, pour qu’une suppression, un retour à une version antérieure ou un réordonnancement côté serveur devienne détectable par votre appareil. Écrit et validé sur web, mobile et serveur ; l’activation attend un plancher de version de l’application mobile (section 10).
- Retirer RSA-2048 (le sceau de repli des communications décrit à la section 3, et le chiffrement des billets de soutien administrateur) au profit du coffre scellé X25519.
- Élargir la liaison au contexte (AAD) et la dérivation de clé par utilisateur à tous les champs chiffrés côté serveur.
- Audit tiers : une revue cryptographique et applicative externe, prévue.
12. Vérification et divulgation
- Vérifiez la crypto : github.com/WiggWiggDev/crypto. Les primitives de KDF, de sceau, de signature et de récupération sont exactement celles décrites ici. Le code source ouvert prouve la conception et les primitives côté client ; à lui seul, il ne prouve pas que nos serveurs les exécutent sans modification, donc des versions client reproductibles et des empreintes de paquet publiées figurent à la feuille de route.
- Signaler une vulnérabilité : voir notre politique de divulgation des vulnérabilités (ou le security.txt, lisible par machine). On offre un refuge de bonne foi pour la divulgation responsable et on vise à accuser réception d’ici un jour ouvrable.
Ce document est versionné et daté. Si la réalité et ce document divergent un jour, c’est un bogue dans l’un des deux. Dites-le-nous.