Sécurité
Un modèle de confiance qui s’explique peut être audité ; un modèle qui se cache, non. Voici ce que fait SecureChat, et aussi ce qu’il ne fait pas.
En bref
- Les messages sont chiffrés de bout en bout entre votre téléphone et le serveur de l’entreprise. Nous ne transportons que du texte chiffré.
- Nous ne générons ni ne voyons jamais les clés privées : la vôtre est créée sur votre téléphone ; celle de l’entreprise, sur son infrastructure.
- Nous vérifions les entreprises et signons leur clé publique ; l’application vous avertit si cette clé change.
- Le chiffrement s’arrête au backend de l’entreprise : ce qu’elle fait du texte déchiffré échappe à notre contrôle.
- La version actuelle du protocole n’offre pas de forward secrecy.
- Nous sommes l’annuaire de clés des deux côtés : sans la protection supplémentaire du lien, un opérateur malveillant actif (nous) pourrait substituer une clé lors du premier contact.
Comment un message est chiffré (enveloppe v1)
Nous utilisons libsodium, une bibliothèque cryptographique auditée et largement utilisée. Voici les éléments de l’enveloppe v1 (sc1) :
| Élément | Construction |
|---|---|
| Identité (votre appareil et l’entreprise) | Paire de clés X25519 |
| Clé de la conversation | 32 octets aléatoires générés par votre téléphone lorsque vous utilisez l’invitation. Si nous la générions, nous la connaîtrions. |
| Distribution de cette clé | Elle est scellée séparément (crypto_box_seal) pour votre clé publique et pour celle de l’entreprise. Nous ne conservons que les deux enveloppes scellées. |
| Chiffrement de chaque message | XChaCha20-Poly1305 avec un nonce aléatoire de 24 octets |
| Données associées | Chaque message est lié à sa conversation, à son expéditeur, à son identifiant et à la version de clé. Un serveur ne peut ni le déplacer vers une autre conversation, ni le dupliquer sous un autre identifiant, ni faire passer l’un de vos messages pour un message de l’entreprise. |
| Remplissage | Jusqu’à des multiples de 256 octets, pour masquer la longueur exacte |
| Signature de la clé de l’entreprise | Ed25519, avec la clé de plateforme |
| Signature de la rotation de clé | Ed25519, avec la clé de signature propre à l’entreprise (voir plus bas) |
| Empreintes | BLAKE2b-256 avec séparation de domaine |
Pièces jointes chiffrées
Les photos et les documents sont chiffrés sur l’appareil qui les envoie (votre téléphone ou le serveur de l’entreprise), exactement comme le texte :
- Chaque fichier a sa propre clé de 32 octets, aléatoire et distincte de celle de la conversation.
- Il est chiffré par blocs de 64 Kio avec XChaCha20-Poly1305. Chaque bloc est authentifié avec l’identifiant de la pièce jointe, sa position et le fait qu’il soit le dernier : réordonner, tronquer ou ajouter des blocs fait échouer le déchiffrement.
- La clé du fichier, son nom, son type, sa taille et son empreinte (BLAKE2b) voyagent à l’intérieur d’un message chiffré ordinaire. À la fin, l’application vérifie l’empreinte ; en cas d’incohérence, elle affiche « Impossible de déchiffrer cette pièce jointe » et jamais un fichier incomplet.
- Nous ne conservons que des octets opaques et un identifiant. Nous voyons la taille du fichier chiffré, pratiquement identique à celle de l’original : les pièces jointes ne sont pas complétées comme les messages. Seules les deux extrémités de la conversation peuvent l’envoyer et le télécharger, via des liens temporaires valables 5 minutes.
- 25 Mo maximum par fichier. Nous ne générons pas de miniatures (nous ne le pouvons pas : nous ne voyons pas le contenu) ; l’application crée l’aperçu après le déchiffrement.
Ce qui est protégé
- Une fuite de notre base de données ou de nos sauvegardes : elles ne contiennent que du texte chiffré.
- Un employé curieux ayant accès aux serveurs.
- Un attaquant passif sur le réseau, ou toute personne qui intercepte le trafic.
- Les notifications push : elles ne contiennent pas le message, ni Apple ni Google ne le voient donc.
- La falsification des messages en transit ou sur nos serveurs : le déchiffrement échoue au lieu d’afficher un texte altéré.
Ce qui n’est pas protégé
- L’autre extrémité est le backend de l’entreprise. C’est là que le message est déchiffré. Si l’entreprise le transfère en clair vers un helpdesk ou un CRM dans le cloud, ce prestataire peut le voir. Si vous travaillez dans un secteur réglementé, demandez à l’entreprise où aboutit le texte.
- Nous, en agissant activement. Votre application reçoit la clé de l’entreprise depuis notre serveur, et l’entreprise reçoit aussi la vôtre par notre intermédiaire. Un opérateur malveillant pourrait substituer l’une ou l’autre. L’application épingle la clé de l’entreprise lors du premier contact et vous avertit si elle change, mais cela ne protège pas ce premier contact précisément. L’empreinte du lien (voir plus bas) comble cette faille lorsque l’invitation arrive par un lien généré avec le SDK.
- Un appareil compromis. Si quelqu’un contrôle votre téléphone ou le serveur de l’entreprise, il peut y lire les messages.
- Les métadonnées. Nous les expliquons plus bas.
Clé de plateforme et vérification des entreprises
Avant qu’une entreprise puisse envoyer des invitations, nous vérifions son existence légale, qu’elle contrôle son domaine (enregistrement DNS) et le numéro WhatsApp depuis lequel elle invite. Nous signons ensuite sa clé publique avec notre clé de plateforme Ed25519. L’application vérifie cette signature et affiche le badge Entreprise vérifiée.
Clé publique de la plateforme (Ed25519, base64url) :
qxh_sOak_wQVqZifJjDcoy-TeWIF3NADjqsjta0GPlw
Ce qui est signé est exactement SecureChat|v1|company-key|<companyId>|<keyVersion>|<clé publique>. Le risque est donc concentré sur nous : si quelqu’un volait la clé de plateforme, il pourrait usurper l’identité d’une marque. C’est pourquoi la vérification du lien existe aussi.
L’entreprise génère sa propre paire de clés sur son infrastructure avec notre SDK (npx @securechat/sdk keygen) et ne nous transmet que la clé publique. Le portail ne propose pas de la générer dans le navigateur : si la clé privée transitait par nos serveurs, la promesse ne serait plus vérifiable.
Entreprises non vérifiées et mode test
Pour qu’une entreprise puisse tester son intégration pendant que nous l’examinons, elle peut créer des invitations de test. Sa clé n’est pas signée comme vérifiée : n’importe qui pourrait donc s’inscrire sous le nom « Banque X » et s’en servir pour usurper l’identité d’une marque. C’est pourquoi :
- L’application n’ouvre une invitation de test que si vous avez activé le Mode test dans Réglages → Diagnostic. Il est désactivé par défaut : un client ordinaire ne se retrouve jamais par erreur dans une conversation de test, même s’il reçoit le lien. Ne l’activez pas parce que quelqu’un vous le demande : une vraie entreprise n’en a pas besoin pour vous parler.
- Ces conversations affichent toujours le bandeau « Entreprise non vérifiée · environnement de test » et jamais le badge d’entreprise vérifiée.
- Elles sont strictement limitées : 5 conversations actives par entreprise, 200 messages de l’entreprise par jour et des invitations de 24 heures maximum. Lorsque nous vérifions l’entreprise, ses conversations de test sont fermées.
Le chiffrement est le même que dans une conversation normale. Ce qui change, c’est la garantie d’identité : dans une conversation de test, nous n’avons pas vérifié qui est l’entreprise.
L’empreinte dans le lien d’invitation
Lorsque l’entreprise crée l’invitation avec le SDK, elle ajoute au lien un fragment #s=…&fp=…. Le navigateur n’envoie pas le fragment au serveur, nous ne le voyons donc pas, mais le lien transite par WhatsApp, un canal que nous ne contrôlons pas. Lors de l’utilisation de l’invitation :
- L’application vérifie que la clé de l’entreprise que nous lui fournissons correspond à l’empreinte
fpdu lien. - L’application lie sa propre clé au secret
sau moyen d’un MAC, et l’entreprise le vérifie.
Si nous substituions l’une des deux clés, l’une des deux extrémités s’en apercevrait. Limites : cela ne couvre que l’utilisation par lien, pas le code court saisi, et les invitations créées manuellement depuis le portail ne contiennent pas ce secret.
Rotation de clé signée par l’entreprise
En plus de sa clé de chiffrement, l’entreprise génère avec le SDK une clé de signature Ed25519 qui reste elle aussi sur son infrastructure ; seule la clé publique nous est transmise. L’application l’épingle lors du premier contact, avec la clé de chiffrement. Lorsque l’entreprise renouvelle sa clé de chiffrement, elle signe le changement avec cette clé de signature : SecureChat|v1|company-key-rotation|<companyId>|<version précédente>|<clé précédente>|<nouvelle version>|<nouvelle clé>. Nous vérifions la signature avant d’accepter la nouvelle clé, et l’application la vérifie à nouveau.
- Rotation signée par la clé épinglée : avertissement discret (« l’entreprise a renouvelé sa clé de sécurité ; l’entreprise elle-même a signé le changement »).
- Non signée, ou signée avec une autre clé : avertissement bien visible. Il est conseillé de confirmer auprès de l’entreprise par un autre canal avant de continuer. Les entreprises qui n’ont pas fourni de clé de signature effectuent toujours leurs rotations ainsi.
Pourquoi c’est important : avec notre seule signature de plateforme, une rotation légitime et une usurpation de notre part se ressembleraient. Avec la signature de l’entreprise, usurper l’identité d’une entreprise que vous avez déjà épinglée exige sa clé de signature, qui ne passe jamais par nous. La signature de plateforme reste obligatoire dans les deux cas. Pour l’instant, la clé de signature ne change pas : la remplacer est traité comme une rotation non signée.
Pas de forward secrecy en v1
Chaque conversation utilise une clé stable. Si votre clé privée ou celle de l’entreprise venait à fuiter, en même temps que les messages chiffrés stockés, les messages antérieurs de cette conversation pourraient eux aussi être déchiffrés. Des protocoles comme Signal renouvellent les clés à chaque message pour l’éviter ; nous l’avons délibérément laissé hors de la première version du protocole, et c’est prévu dans notre feuille de route.
Métadonnées
Même si nous ne voyons pas le contenu, nous voyons qui échange avec quelle entreprise, quand et à quelle fréquence, la taille approximative de chaque message (arrondie à 256 octets), la taille et la date de chaque pièce jointe, les adresses IP et des informations sur l’appareil. Cela suffit pour en déduire beaucoup, c’est pourquoi nous le déclarons dans la politique de confidentialité.
L’historique est lié à votre appareil : si vous le perdez, vous récupérez chaque conversation avec une nouvelle invitation de l’entreprise, qui scelle à nouveau la clé pour votre nouvel appareil.
Signaler une vulnérabilité
Écrivez-nous à soporte@securechat-app.com avec l’objet « Sécurité ». Merci de nous laisser un délai raisonnable pour la corriger avant de la rendre publique.