
Messagerie chiffrée en ligne de commande avec cryptographie post-quantique, protocole Double Ratchet et anonymat Tor. Fonctionnalités : phrase de passe sous contrainte, authentification déniable et durcissement au niveau du système d'exploitation via seccomp-bpf et mlockall.
op4 — Messagerie sécurisée en terminal
Op4 est une application de messagerie chiffrée fonctionnant en terminal, écrite en Rust. Elle propose des messages privés chiffrés de bout en bout avec une cryptographie post-quantique, acheminés entièrement via le réseau Tor, de sorte que ni le contenu de vos messages ni votre adresse IP ne soient exposés à quiconque — pas même à la personne à qui vous parlez.
op4 permet à deux personnes d'échanger des messages privés sans qu'aucune des deux ne révèle son adresse IP ou sa véritable identité. Chaque message est :
op4 s'exécute entièrement dans le terminal. Il n'a ni interface graphique, ni composant navigateur, ni compte cloud. Le seul processus externe qu'il contacte est le démon Tor tournant sur votre propre machine.
Toutes les options de téléchargement — AppImage, archive source, clone et compilation, et installateur automatisé — sont documentées dans le Guide de téléchargement et d'installation. La dernière version est disponible sur la page des versions.
Sur Debian et Ubuntu, install/setup.sh gère tout en une seule commande :
chaîne d'outils Rust, dépendances de compilation, Tor, configuration du port de contrôle,
compilation du binaire, utilisateur système, répertoire de données et profil AppArmor.
git clone https://github.com/Opfour/op4.git
cd op4
sudo bash install/setup.sh
Après la fin du script, vous devez vous déconnecter et vous reconnecter avant de lancer op4. L'installateur ajoute votre utilisateur au groupe
debian-torafin qu'il puisse lire le fichier cookie de Tor. Linux n'applique pas les changements de groupe aux sessions déjà ouvertes — une nouvelle connexion est requise.Ignorer cette étape entraînera un échec au démarrage d'op4 avec :
Permission denied reading /run/tor/control.authcookie
Ensuite, vérifiez que le hash source affiché par le script correspond au hash publié pour votre version avant de faire confiance au binaire.
Lorsqu'op4 démarre, il affiche un hash source couvrant tous les fichiers source Rust,
Cargo.toml, Cargo.lock et build.rs. Comparez-le avec la valeur
ci-dessous pour la version que vous avez installée.
Vous pouvez également le vérifier sans lancer l'application complète :
op4 --print-hash
Si le hash ne correspond pas, n'utilisez pas le binaire — il a été soit compilé à partir d'un commit différent, soit falsifié.
Installez d'abord les dépendances, puis exécutez le script :
Chaîne d'outils Rust (épinglée à la version 1.89.0 via rust-toolchain.toml) :
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
Tor et dépendances de compilation :
# Fedora
sudo dnf install tor gcc pkg-config openssl-devel
# Arch
sudo pacman -S tor base-devel pkg-config openssl
Configurer le port de contrôle Tor — ajoutez dans /etc/tor/torrc :
ControlPort 9051
CookieAuthentication 1
sudo systemctl restart tor
Ajoutez votre utilisateur au groupe Tor :
sudo usermod -aG tor $USER # Fedora / Arch
Vous devez vous déconnecter et vous reconnecter après cette étape. Les changements d'appartenance à un groupe ne sont pas appliqués aux sessions actives. Jusqu'à ce que vous le fassiez, op4 échouera avec
Permission denied reading /run/tor/control.authcookie.Pour appliquer le changement sans déconnexion complète, exécutez :
newgrp tor
Compilation et installation :
git clone https://github.com/Opfour/op4.git
cd op4
cargo build --release
sudo bash install/setup.sh
op4
# ou, sans installation système :
./target/release/op4
Au premier lancement, op4 vous guidera pour définir une phrase de passe normale
et une phrase de passe de contrainte, puis générera vos clés d'identité. Votre
coffre est stocké dans ~/.local/share/op4/vault.op4.
Noyau minimum : 4.15 (5.4+ recommandé). Architecture : x86-64 (aarch64 devrait fonctionner mais n'est pas testé).
Deux personnes ont besoin chacune d'op4 installé, de Tor en cours d'exécution et de leur coffre déverrouillé. L'échange est asymétrique : une personne envoie d'abord son code de contact, l'autre l'ajoute, puis envoie son premier message, qui arrive comme une demande en attente que la première personne doit accepter.
Au premier lancement, op4 demande une phrase de passe normale et une phrase de passe
de contrainte, puis génère vos clés d'identité. Cela ne se produit qu'une seule fois.
Votre coffre est stocké dans ~/.local/share/op4/vault.op4.
$ op4
Votre code de contact contient l'intégralité de votre trousseau de clés publiques et votre adresse
.onion. L'autre personne en a besoin pour vous joindre.
2 ou →)e pour exporter votre code de contactop4:Votre code de contact n'est pas secret. Il peut être partagé publiquement sans risque. Il ne contient que vos clés publiques et votre adresse onion — aucun matériel privé.
Une fois que vous avez son code de contact :
a pour ajouter un contactop4: et appuyez sur Entrée↑/↓, puis Entrée)3 ou →)Ce premier message initie la poignée de main chiffrée et est délivré
à leur adresse .onion via Tor. Ils le verront comme une demande de contact en attente.
Quand quelqu'un vous envoie un premier message, un badge apparaît sur l'onglet Contacts indiquant le nombre de demandes en attente.
2)p pour consulter les demandes en attenteÉchap pour refuser et supprimer)Une fois acceptée, le Double Ratchet est initialisé et la conversation est immédiatement disponible dans l'onglet Messages.
Avant de faire confiance à un contact, confirmez que son empreinte correspond à ce qu'il affiche sur son propre écran. Cela empêche une attaque de l'homme du milieu lors de l'échange initial de contact.
A3F2:91BC:…Si vous pensez que vos clés d'identité ont pu être compromises :
4 ou naviguez vers la droite)r pour faire la rotation des clésop4 utilise un protocole Double Ratchet (similaire au Signal Protocol) pour la secreté de transmission (forward secrecy). Cela signifie :
L'étape KEM combine X25519 et ML-KEM-768 comme suit :
shared_secret = HKDF(X25519_ss || MLKEM_ss)
Un attaquant doit casser les deux algorithmes pour compromettre l'échange de clés. Cela protège contre un adversaire quantique (ML-KEM-768) tout en restant sûr contre les attaques classiques si ML-KEM-768 présente une faille inconnue (repli X25519).
Les messages sont authentifiés avec HMAC-SHA256 en utilisant une clé dérivée de l'état partagé du ratchet. Les deux parties détenant la même clé HMAC, l'une ou l'autre aurait pu produire un MAC donné. C'est la même propriété de non-répudiation utilisée par OTR et Signal : les messages ne peuvent pas être attribués cryptographiquement à un expéditeur spécifique dans le cadre d'une procédure judiciaire.
Le fichier de coffre dans ~/.local/share/op4/vault.op4 stocke tous les contacts,
conversations et clés d'identité. Il est protégé par deux clés indépendantes
dérivées via Argon2id :
op4 crée un service caché Tor v3 pour votre boîte de réception. Votre adresse
.onion est dérivée de manière déterministe de votre clé d'identité (via HKDF), donc
elle est stable entre les redémarrages sans avoir besoin de stocker une clé séparée. Les messages
sortants sont envoyés via le proxy SOCKS5 de Tor. Votre véritable adresse IP n'apparaît
jamais dans aucun paquet réseau lié à op4.
Le trafic de couverture (messages factices à distribution de Poisson envoyés à soi-même, intervalle moyen de 30 secondes) empêche un observateur réseau de savoir si vous messagiez activement avec quelqu'un en surveillant le volume de trafic.
apparmor/op4.profile) — restreint l'accès au système de fichiers
au seul répertoire du coffre, aux périphériques terminal et à Tor.┌─────────────────────────────────────────────────────────────┐
│ op4 process │
│ │
│ ┌──────────┐ ┌──────────────────┐ ┌────────────────┐ │
│ │ TUI │ │ Double Ratchet │ │ Tor Transport │ │
│ │ (ratatui)│──▶│ + Hybrid PQ │──▶│ nym_client.rs │ │
│ │ │ │ Crypto │ │ │ │
│ └──────────┘ └──────────────────┘ └───────┬────────┘ │
│ │ │
│ ┌──────────────────────────────┐ │ │
│ │ Encrypted Vault │ SOCKS5 / control port │
│ │ ~/.local/share/op4/vault.op4│ │ │
│ └──────────────────────────────┘ │ │
└────────────────────────────────────────────────┼───────────┘
│
┌────────────▼────────────┐
│ Tor daemon │
│ 127.0.0.1:9050 (SOCKS) │
│ 127.0.0.1:9051 (ctrl) │
└────────────┬────────────┘
│
Tor network
│
┌────────────▼────────────┐
│ Peer's .onion address │
│ (their hidden service) │
└─────────────────────────┘
op4/
├── src/
│ ├── main.rs Point d'entrée, séquence de démarrage
│ ├── error.rs Types d'erreur unifiés
│ ├── crypto/
│ │ ├── keys.rs Paires de clés KEM hybride + signature
│ │ ├── primitives.rs AEAD, HKDF, HMAC, Argon2id
│ │ ├── ratchet.rs Implémentation du Double Ratchet
│ │ ├── hmac_auth.rs Étiquettes d'authentification non répudiable
│ │ └── handshake.rs Accord de clés initial (style X3DH)
│ ├── network/
│ │ ├── nym_client.rs Transport par service caché Tor
│ │ └── message.rs Format du message filaire + padding
│ ├── storage/
│ │ └── vault.rs Coffre chiffré (Argon2id + AEAD)
│ ├── identity/
│ │ ├── profile.rs Codes de contact, contacts stockés
│ │ └── revocation.rs Enregistrements de révocation de clé
│ ├── hardening/
│ │ ├── memory.rs mlockall, RLIMIT_CORE, dumpable
│ │ └── seccomp.rs Filtre d'appels système seccomp-bpf
│ └── ui/
│ ├── app.rs Boucle d'événements TUI et machine d'état
│ ├── contacts.rs Rendu de l'onglet Contacts
│ ├── conversation.rs Rendu de l'onglet Messages
│ ├── settings.rs Rendu de l'onglet Paramètres
│ ├── duress.rs Rendu de la boîte de réception de contrainte
│ ├── input.rs Nettoyage des entrées (suppression CSI/OSC)
│ └── passphrase.rs Invites de phrase de passe sécurisées
├── apparmor/
│ └── op4.profile Profil MAC AppArmor
├── install/
│ └── setup.sh Script d'installation système
├── build.rs Embarque le hash source à la compilation
├── deny.toml Règles de licence et d'avis pour cargo-deny
├── rust-toolchain.toml Épingle Rust 1.89.0
└── docs/ Cette documentation
Version : 0.2.0-dev (pré-version)
op4 est en développement actif. Les couches suivantes sont complètes et testées :
Toutes les couches sont maintenant reliées de bout en bout :
PublicKeyBundle codé en Base58
(votre jeu complet de clés publiques + adresse onion).Toutes les limitations connues ont été résolues. L'application est désormais en statut de fonctionnalités complètes pour la version 0.2.0-dev :
L'authentification non répudiable HMAC est entièrement câblée. Chaque message
sortant porte une étiquette HMAC-SHA256 calculée à partir de la clé de ratchet par message
sur (conversation_id || message_counter || ciphertext). Les messages entrants sont
vérifiés avant d'être acceptés ; les étiquettes remplies de zéros provenant d'anciens pairs
sont tolérées pour la rétrocompatibilité.
L'historique des messages persiste entre les redémarrages. Le journal complet de la
conversation est chiffré avec une clé dérivée via HKDF propre à la conversation et stocké
dans le champ message_log_ct du coffre. Les messages sont chargés depuis le coffre
lorsqu'une conversation est ouverte et réécrits après chaque envoi ou réception.
Les demandes de contact entrantes provenant de personnes inconnues sont mises en file
d'attente plutôt que supprimées. L'onglet Contacts affiche un badge lorsqu'il y a des
demandes en attente. Appuyez sur [p] pour les consulter : vous voyez l'empreinte de
l'expéditeur et son premier message, tapez un nom et appuyez sur Entrée pour accepter
(ou Échap pour refuser). Une fois acceptée, le contact est ajouté, le Double Ratchet est
initialisé et le message initial est sauvegardé dans le coffre.
Le coffre de contrainte est préservé entre les sauvegardes. Le format du fichier de
coffre (v2) stocke les longueurs exactes du texte chiffré dans l'en-tête, de sorte que le
déchiffrement AEAD opère sur les véritables octets plutôt que sur des sections remplies de
zéros. La section chiffrée de contrainte est stockée textuellement à chaque appel save(),
ce qui maintient la validité de la phrase de passe de contrainte indéfiniment.
Clé de bootstrap dédiée au Double Ratchet. Une paire de clés X25519 séparée
(identity_ratchet_secret) est générée au premier lancement et incluse dans le code de
contact sous le nom . Le ratchet d'Alice est initialisé avec le
de Bob plutôt qu'avec sa clé d'identité KEM, séparant ainsi les rôles des clés.
| Version | Hash source |
|---|
0.3.0 | 80820cb41a63575d2c139dadd425d13d1e87e62a9d60200ae7b894ae2e9ad8ed |
0.3.1 | 48115efb12747fa78b627ddbf7a56c46169f59e777d7d7508941bf89e4fe7521 |
0.2.0-dev | 35740577f6c4a4f19c5a08fe85b1f78a10347f2ba9dd7642d126552266bfa5a5 |
0.1.0 | e1a94761c7d3fa589ba892b47d5295aa417f95aee126809d51a7e7fb7e78982c |
| Distribution | Statut |
|---|
| Ubuntu 22.04 / 24.04 | Pris en charge |
| Debian 12 | Pris en charge |
| Fedora 39+ | Pris en charge |
| Arch Linux (actuel) | Pris en charge |
| Tails OS | Pris en charge (guide d'installation) |
| macOS / Windows / WSL1 | Non pris en charge |
| Touche | Action |
|---|
1 / ← → | Changer d'onglet (Contacts / Messages / Paramètres) |
↑ ↓ | Déplacer la sélection |
Entrée | Ouvrir la conversation / confirmer |
Échap | Annuler / revenir en arrière |
e | Exporter votre code de contact (onglet Contacts) |
a | Ajouter un contact (onglet Contacts) |
p | Consulter les demandes en attente (onglet Contacts) |
d | Supprimer le contact sélectionné (onglet Contacts) |
r | Rotation des clés (onglet Paramètres) |
q | Quitter |
| Objectif | Algorithme |
|---|
| Dérivation de la clé du coffre | Argon2id (m=64 MiB, t=3, p=1) |
| Chiffrement du coffre | ChaCha20-Poly1305 (clé 256 bits, nonce 96 bits) |
| Chiffrement des messages | ChaCha20-Poly1305 (clé par message issue du ratchet) |
| Dérivation de clé (ratchet) | HKDF-SHA256 |
| Authentification non répudiable | HMAC-SHA256 |
| Échange de clés classique | X25519 |
| Échange de clés post-quantique | ML-KEM-768 (FIPS 203) |
| Signatures classiques | Ed25519 |
| Signatures post-quantiques | ML-DSA-65 (FIPS 204) |
| Anonymat du transport | Services cachés Tor v3 (.onion) |
ratchet_pubratchet_pubL'onglet Paramètres est entièrement fonctionnel. L'adresse SOCKS5 de Tor et le seuil de suppression automatique peuvent être modifiés en ligne. La rotation des clés (génère une nouvelle paire de clés, diffuse un certificat de révocation signé à tous les contacts, rafraîchit le code d'exportation) et la révocation de mise à la retraite des clés sont toutes deux câblées et opérationnelles.
La révocation de clés est câblée de bout en bout. Les structures RevocationCertificate
sont signées avec la paire de clés hybride Ed25519+ML-DSA-65 et envoyées à tous les contacts
sous forme de messages WireMessageType::Revocation via Tor.