Version 1.0.0 — Avril 2026
Classification : Public
OV Message est une application de messagerie chiffrée de bout en bout fonctionnant sans serveur centralisé. Les messages sont chiffrés avant envoi et déchiffrés à réception, indépendamment du canal de transport utilisé. L'implémentation actuelle utilise le réseau SMS, mais le protocole de chiffrement est agnostique au transport — il fonctionne sur tout canal capable de transmettre du texte.
Architecture sans serveur : Ce choix délibéré élimine un point de défaillance unique, supprime la nécessité de faire confiance à un opérateur tiers, et ne requiert aucune connexion Internet.
Le présent document décrit les mécanismes cryptographiques employés, les choix de conception, et les limites connues du système.
Opérateur, FAI, attaquant réseau — Chiffrement E2E, le canal ne voit que du texte chiffré.
HMAC-SHA256, toute altération invalide le tag d'authentification.
Anti-rejeu par stockage de tags (128 bits, indépendant de l'horloge).
Chiffrement par flux basé sur SHA3-256, aucune correspondance fixe caractère-à-caractère.
Index aléatoire par message, un couple (clair, chiffré) n'aide pas pour un autre message.
Mode Forteresse, suppression automatique des messages non authentifiés.
Cellebrite, JTAG — KEK/DEK, clés chiffrées au repos, DEK détruit au verrouillage.
Verrouillage automatique natif, kill du process, RAM libérée par l'OS.
Mode Panic, destruction des données via mot de passe alternatif.
Flag système anti-capture sur toutes les fenêtres de l'application.
Backup désactivé sur tous les domaines (cloud, local, transfert).
Argon2id (64 Mo par tentative) + 3 échecs = Panic automatique.
Deep links bloqués quand un mot de passe est actif.
Si une clé existe, l'application chiffre systématiquement. Aucun envoi en clair possible.
Isolation par contact, chaque clé produit des alphabets et clés MAC indépendants.
Notifications anonymisées (Mode Forteresse), aucun nom, aucun aperçu.
Compromission du système d'exploitation (root/jailbreak actif avec keylogger). Attaque par canal auxiliaire sur le matériel cryptographique.
| Composant | Technologie |
|---|---|
| Framework | React Native 0.83 / Expo 55 |
| Moteur | Hermes (bytecode compilé) |
| Cryptographie | Bindings natifs OpenSSL (SHA3-256, HMAC-SHA256, AES-256-GCM, HKDF, Argon2id, ECDH X25519) |
| Stockage sensible | Android Keystore |
| Stockage non sensible | Base de données locale |
Keystore sécurisé — Android Keystore + chiffrement DEK (AES-256-GCM)
Keystore sécurisé — Android Keystore
Keystore sécurisé — AES-256-GCM sous KEK dérivée d'Argon2id
Stockage local — Stockées sous forme chiffrée (format OV)
Séparation des responsabilités : Toute la logique cryptographique est isolée dans une couche de services dédiée, séparée de l'interface utilisateur. Chaque service a une responsabilité unique.
OV Message utilise un chiffrement par flux basé sur le hachage (hash-based stream cipher). Chaque caractère du message est chiffré individuellement par un index de substitution dérivé de SHA3-256, dépendant de la position, d'un index aléatoire unique au message, et d'une sous-clé dérivée de la clé de contact.
Pas un chiffrement par substitution classique : Il n'existe aucune table de correspondance fixe entre caractères clairs et caractères chiffrés.
Les primitifs standards (AES-CTR, ChaCha20) produisent une sortie binaire. Leur utilisation sur un canal SMS imposerait un encodage supplémentaire (Base64, Base85) qui augmente la taille du message de 33 à 50 %. Sur SMS, chaque caractère compte.
Le cipher d'OV Message opère directement dans l'espace Unicode. Le texte clair est transformé en texte chiffré sans passer par une représentation binaire intermédiaire. Le ratio est de 1:1 — un caractère clair produit un caractère chiffré.
Le design retenu utilise SHA3-256 comme générateur pseudo-aléatoire indexé par position, avec un index aléatoire par message et une sous-clé dérivée par HKDF. Chaque caractère est chiffré indépendamment avec une entropie de 256 bits par position.
Compromis assumé : Un cipher non standard en échange d'un ratio de taille optimal sur un canal à bande passante limitée. Les primitifs standards (AES-256-GCM, HKDF-SHA256, HMAC-SHA256) sont utilisés pour toutes les autres opérations cryptographiques.
Unicité garantie : Chaque message utilise une sous-clé cryptographiquement indépendante. Deux messages identiques envoyés au même contact produisent des chiffrés complètement différents.
SHA3-256 à chaque position, relation non linéaire entre clair et chiffré.
L'index aléatoire change l'intégralité du chiffré pour un même message.
Aucune correspondance fixe caractère-à-caractère.
Sous-clé unique par message, connaître un couple (clair, chiffré) n'aide pas pour un autre message.
Le système utilise des alphabets Unicode conçus pour couvrir 100+ langues en entrée et produire une sortie dans un espace Unicode distinct.
La clé MAC est dérivée indépendamment de la clé de chiffrement via HKDF-SHA256 avec séparation de domaine. Chaque conversation produit une clé MAC unique.
Le tag HMAC-SHA256 est calculé sur la concaténation de données authentifiées additionnelles (identifiant de conversation, index du message) et du texte chiffré. Le tag est tronqué à 128 bits.
Toute modification du chiffré invalide le tag.
L'index aléatoire unique par message rend chaque tag unique.
La vérification du tag est obligatoire au déchiffrement.
La clé MAC est dérivée avec un info string différent de la clé AES des fichiers.
Chaque clé de contact est générée localement avec un CSPRNG. Les clés ont une longueur variable et une haute entropie. La longueur variable empêche un attaquant de déterminer la taille de la clé à partir de métadonnées.
OV Message propose trois méthodes d'échange hors bande :
| Méthode | Canal | Mécanisme |
|---|---|---|
| En personne | QR code scanné physiquement | Transmission directe de la clé |
| Par visio | Appel vidéo externe | ECDH sur courbe X25519 |
| Par code | Voix, texte, ou tout canal | ECDH sur courbe X25519 |
Échange ECDH : Chaque participant génère une paire de clés éphémère sur X25519. Les clés publiques sont échangées, chacun calcule le secret partagé ECDH dérivé en clé de contact via SHA3-256. Les clés privées éphémères sont détruites après l'échange.
Un pool de clés pré-généré localement pour chaque contact. Chaque clé indexée par un numéro.
Pool chiffré avec AES-256-GCM (clé dérivée par HKDF-SHA256) avant échange.
Sélection par index, seul le numéro transite. Jamais la clé elle-même.
Chaque clé consommée est physiquement supprimée, garantissant la forward secrecy.
| Usage | Algorithme | Détails |
|---|---|---|
| Hachage mot de passe | Argon2id (m=64 Mo, t=3, p=1, L=32) | Sel aléatoire par hash |
| KEK | Argon2id (m=64 Mo, t=3, p=1, L=32) | Sel séparé du hash |
| Clé AES fichiers | HKDF-SHA256 | Info string dédié |
| Clé AES pool | HKDF-SHA256 | Info string dédié |
| Clé MAC | HKDF-SHA256 | Info string dédié + ID conversation |
| Échange ECDH | ECDH X25519 + HKDF-SHA256 | Clés éphémères par échange |
| Permutation charset | Dérivation déterministe | Entrée différente par contact |
Séparation de domaine : Chaque contexte utilise un info string ou un sel distinct, garantissant qu'une même clé de contact produit des clés dérivées indépendantes pour chaque usage.
Protéger les clés de contact contre l'extraction forensique (Cellebrite, JTAG, extraction RAM) en cas de saisie physique du téléphone.
Dérivée du mot de passe via Argon2id (m=64 Mo, t=3, p=1). N'est jamais stockée — dérivée à la demande au login.
Clé aléatoire, enveloppée sous KEK via AES-256-GCM. Chargée en mémoire au login, détruite au verrouillage (kill du process).
Chaque clé chiffrée individuellement avec le DEK (AES-256-GCM). Déchiffrement lazy (à la demande).
Sans mot de passe configuré, les clés restent dans le keystore sécurisé (protégées par Android Keystore). La migration vers le mode chiffré est transparente à la première configuration d'un mot de passe.
Les fichiers partagés entre contacts sont chiffrés avec AES-256-GCM. La clé AES est dérivée par HKDF-SHA256 à partir de la clé de contact et d'un sel aléatoire de 16 octets, avec un info string dédié. Un IV de 12 octets est généré aléatoirement.
Overhead total : 44 octets (sel 16 + IV 12 + tag 16).
L'authentification GCM garantit l'intégrité du chiffré et de l'AAD. Une vérification de cohérence du nom de fichier est effectuée après déchiffrement.
Indépendant de l'horloge : Aucun horodatage, aucun TTL, aucune synchronisation requise entre appareils.
| Seuil | Action |
|---|---|
| 1 500 tags stockés | Alerte : rotation de clé recommandée |
| 1 800 tags stockés | Alerte : rotation fortement recommandée |
| 1 999 tags stockés | Alerte : rotation urgente |
À chaque rotation de clé, le magasin de rejeu est effacé. La nouvelle clé produit une nouvelle clé MAC, donc les anciens tags ne peuvent pas être rejoués.
Le mode Forteresse est un filtre actif qui supprime automatiquement tout message entrant n'ayant pas pu être authentifié. Il constitue une protection contre le phishing, l'usurpation d'identité et les messages non sollicités.
Le numéro est un contact OV Message avec une clé de chiffrement. Échec = message supprimé.
Le message est au format chiffré OV. Échec = message supprimé.
Le tag HMAC-SHA256 est valide et le déchiffrement réussit. Échec = message supprimé.
Couche native : intercepte les messages avant diffusion au système. Les numéros inconnus sont bloqués immédiatement, sans notification.
Couche applicative : validation cryptographique complète (HMAC + déchiffrement) pour les messages ayant passé le premier filtre.
En mode Forteresse, les notifications sont génériques (aucun nom d'expéditeur, aucun aperçu du contenu). Un attaquant observant l'écran de verrouillage ne peut pas déterminer qui communique avec l'utilisateur.
Deux niveaux de destruction d'urgence. Déclenchement par mot de passe alternatif dédié. Si l'auto-destruction est activée, 3 échecs de mot de passe déclenchent automatiquement le mode Panic.
| Donnée | Panic (destruction complète) | Panic clés (clés uniquement) |
|---|---|---|
| Clés de contact | Détruites | Détruites |
| DEK / KEK | Détruits | Détruits |
| SMS physiques | Supprimés | Préservés |
| Contacts du répertoire | Supprimés | Préservés |
| Conversations, paramètres | Effacés | Préservés |
| Messages chiffrés | Supprimés | Présents mais indéchiffrables |
| Caches mémoire (RAM) | Écrasés puis vidés | Vidés |
| Réversibilité | Non | Non |
Indétectable : Les deux modes sont silencieux — aucune alerte visuelle, l'application affiche l'écran principal comme après un login normal.
Un module natif programme la terminaison du process via une alarme système exacte, immune au Doze mode. Quand le timer expire, le process est tué par l'OS et toute la RAM est libérée (DEK, clés, données sensibles). Si l'application revient en premier plan avant l'expiration, l'alarme est annulée.
Flag système empêchant la capture d'écran et l'enregistrement.
Backup désactivé sur tous les domaines (cloud, local, transfert).
Android Keystore pour les secrets (extraction requiert le PIN/biométrie).
L'application fonctionne sans serveur d'échange de clés permanent, rendant le Double Ratchet impraticable. Un hash ratchet causerait une désynchronisation sur les messages perdus ou réordonnés.
Sécurité en mode clé statique : Chaque message dérive une sous-clé indépendante via HKDF-SHA256. La compromission d'une sous-clé ne compromet pas les autres messages. Le pool de clés apporte une forward secrecy manuelle — la suppression d'une clé consommée rend les messages passés indéchiffrables.
Le canal de transport expose des métadonnées (expéditeur, destinataire, horodatage). OV Message ne peut pas masquer ces informations car elles font partie du protocole de transport sous-jacent.
Les messages sont paddés de manière déterministe. Un observateur peut approximer la longueur du message clair. Ce compromis est accepté car les métadonnées de transport fuient déjà plus d'informations que la longueur du message.
Audit : Le cipher par flux basé sur SHA3-256 est un design original dont la sécurité repose sur les propriétés PRF bien établies de SHA3-256. Un audit cryptographique formel indépendant est planifié et sera publié. Toutes les autres opérations cryptographiques utilisent des primitifs standards audités.
La sécurité repose sur la confidentialité de la clé partagée. L'échange en personne (QR code) ou par visio (ECDH) constitue une vérification d'identité directe. L'échange par code vocal repose sur la reconnaissance vocale, qui est moins fiable.
OV Message cible un modèle de menace que les messageries conventionnelles (Signal, WhatsApp, Olvid) n'adressent pas : fonctionnement sans serveur ni connexion Internet, résilience à la saisie physique du téléphone, et destruction d'urgence des données sous contrainte.
Destruction complète ou clés uniquement, indétectable par l'attaquant.
Terminaison du process, libération de la RAM par l'OS.
Filtrage anti-phishing en 3 étapes avec notifications anonymisées.
Zéro coût d'infrastructure, aucune dépendance à un tiers, résistant à la censure.
| Composant | Paramètre | Valeur |
|---|---|---|
| Chiffrement messages | Hash par position | SHA3-256 (256 bits) |
| Chiffrement messages | Index aléatoire | Haute entropie (CSPRNG) |
| Chiffrement messages | Sous-clé par message | HKDF-SHA256 (256 bits) |
| Chiffrement messages | Alphabets | Dérivés par contact |
| HMAC | Algorithme | HMAC-SHA256 |
| HMAC | Tag | 128 bits |
| HMAC | Dérivation | HKDF-SHA256 avec séparation de domaine |
| Argon2id | Mémoire (m) | 64 Mo |
| Argon2id | Itérations (t) | 3 |
| Argon2id | Parallélisme (p) | 1 |
| Argon2id | Sortie | 256 bits |
| AES-256-GCM | Clé | 256 bits |
| AES-256-GCM | IV | 96 bits |
| AES-256-GCM | Tag | 128 bits |
| KEK/DEK | DEK | 256 bits aléatoires |
| KEK/DEK | Enveloppement | AES-256-GCM sous KEK |
| Génération de clés | Entropie | Haute entropie (CSPRNG) |
| ECDH | Courbe | X25519 (128 bits de sécurité) |
| ECDH | Clés éphémères | Détruites après échange |
| Anti-rejeu | Stockage | Par contact, par direction |
| Fichiers | Chiffrement | AES-256-GCM + HKDF |
OV Message — Chiffrement sans serveur, sans dépendance, sans concession sur la sécurité.