Protocole mobile
Comment l'application mobile signe chaque étape — et ce que ça implique
Un parcours détechnilisé dans le protocole Ezkey : enrollment, proof tokens et chaînage cryptographique de bout en bout.
01 — Le monde dans lequel on vit
En 2026, pour la majorité des équipes, l'authentification forte se résume encore à un mot de passe combiné à un code envoyé par SMS ou par courriel. Au Canada comme ailleurs, les SMS circulent sans chiffrement de bout en bout sur des réseaux qui ne garantissent aucune confidentialité. Les courriels ne font pas mieux comme canal de transmission de secrets temporels. Et pourtant, c'est sur ces vecteurs que repose la majorité des dispositifs MFA en production aujourd'hui.
Les passkeys arrivent, et c'est une bonne nouvelle. Construits sur FIDO2, ils proposent un modèle robuste ancré dans les plateformes, progressivement adopté par les grands acteurs. Mais leur déploiement reste inégal, particulièrement pour les équipes back-end-first qui travaillent loin des frameworks web côté client.
Le vrai problème n'est peut-être pas la forme du code — six chiffres, lien magique, notification push. Le problème, c'est le modèle de confiance sous-jacent : qui valide quoi, et comment cette validation est-elle ancrée cryptographiquement ?
Ezkey propose une troisième voie. Pas une alternative aux passkeys : une solution plus modeste et pragmatique, supérieure aux codes OTP et aux SMS sur le plan de la sécurité cryptographique, taillée pour les équipes qui veulent comprendre et contrôler ce qui se passe dans leur chaîne d'authentification.
02 — L'ancrage : la confiance vient du back-end
Le modèle Ezkey repose sur un principe déjà décrit dans Ezkey en un coup d'œil : l'installation back-end auto-hébergée est le socle de confiance. Pas une plateforme tierce, pas un service cloud opaque — l'instance Ezkey déployée dans l'environnement de l'organisation, sous son contrôle direct.
Dans ce modèle, l'application mobile n'est pas un bouton de confirmation. Elle est un participant cryptographique à part entière. Elle détient une clé privée protégée par les mécanismes de sécurisation de la plateforme : sur Android, cette clé est générée directement dans l'Android Keystore, et — lorsque le matériel le permet — dans un module dédié à la protection cryptographique matérielle (StrongBox). La clé ne quitte jamais ce périmètre ; elle ne transite pas dans la mémoire de l'application, n'est pas exportable, n'est jamais stockée en clair.
C'est la différence fondamentale avec un modèle push-to-approve traditionnel. Dans un tel modèle, l'application reçoit une notification et l'utilisateur tape « Oui ». Le canal de confiance est humain. Ici, le canal de confiance est cryptographique. L'application signe.
03 — L'inscription : prouver qu'on possède la clé
L'inscription se déroule en deux phases — bind puis verify — qui forment une séquence cryptographiquement liée.
Bind. L'application se présente avec un enrollmentProofToken — un jeton opaque fourni hors bande par l'équipe d'administration lors de la création du compte. Ce jeton est anti-énumération : impossible de deviner l'existence d'une inscription en essayant des valeurs arbitraires.
Le back-end répond en fournissant sa clé publique d'intégration et une signature de la réponse. L'application vérifie cette signature avant d'aller plus loin. C'est la première protection contre un intermédiaire malveillant : si une réponse injestée est forgée, la vérification de la signature échoue et le flux s'arrête là.
Verify. L'application génère une paire de clés EC P-256 directement dans l'Android Keystore. Elle construit ensuite une charge signée canonique :
enrollmentProofToken|enrollmentId|challengeResponse|devicePublicKey
Elle signe cette chaîne avec sa clé privée et envoie la signature au back-end avec la clé publique correspondante. Ce qui est signé ici, ce n'est pas juste un challenge : c'est l'intégralité du contexte de l'inscription. La normalisation est stricte — séparateur |, encodage UTF-8, aucune ambiguïté sur ce que couvre la signature.
Ce niveau de précision n'est pas de la rigueur pour la rigueur : c'est ce qui rend la preuve vérifiable et non réinterprétable. Le back-end vérifie et contre-signe à son tour. L'application valide cette dernière signature avant de considérer l'inscription comme complète. À ce stade, les deux parties ont prouvé leur identité cryptographique dans les deux sens.
Schématiquement, le flux d'inscription ressemble à ceci :
bind · enrollmentProofToken (hors bande)
Back-end
verify · clé publique + contexte signé ECDSA · enrollmentProofToken|enrollmentId|challenge|devicePublicKey
Back-end
04 — Le Proof Token : matière non répétable
Ezkey utilise trois types de jetons dans son protocole, chacun avec un rôle précis.
enrollmentProofToken— fourni hors bande à l'inscription, stable pour toute la durée du flux d'enrollment. Il identifie le contexte d'inscription de façon opaque, sans exposer de surface de devinette.deviceProofToken— généré par l'application à chaque sondage, à partir du générateur de nombres aléatoires cryptographiques de la plateforme. Il est signé avec la clé d'inscription. Son rôle : prouver la fraîcheur de l'appel. Rejouer undeviceProofTokenprécédent ne fonctionne pas.authAttemptProofToken— émis par le back-end pour chaque tentative d'authentification, à usage unique. C'est la matière centrale du chaînage entrependingetrespond.
L'analogie la plus simple : pensez à une déclaration notariée. Chaque acte porte une date précise, un contexte spécifique, et une signature unique. On ne peut pas photocopier l'acte et l'utiliser dans un contexte différent. Les proof tokens fonctionnent sur ce même principe.
05 — L'authentification : un aller-retour signé de bout en bout
L'authentification se déroule en deux étapes : pending puis respond.
Pending. L'application se signale avec son deviceProofToken signé — la preuve que cet appel est frais. Le back-end, s'il dispose d'une tentative d'authentification en attente pour ce dispositif, répond avec authAttemptProofToken, signé par la clé d'intégration établie lors de l'inscription.
L'application vérifie cette signature avant d'afficher quoi que ce soit à l'utilisateur. Ce point est décisif. Si un proxy malveillant intercepte la communication et injecte une fausse réponse, il ne peut pas la signer avec la clé d'intégration : cette clé est connue seulement du back-end légitime, et elle a été ancrée dans l'application lors de l'inscription. La vérification échoue, l'application rejette la réponse, l'utilisateur ne voit rien.
Le maillon de chaîne. L'authAttemptProofToken reçu dans pending est précisément la matière signée dans respond. L'application signe :
authAttemptProofToken|true
— ou false si l'utilisateur refuse. Ce n'est pas un détail d'implémentation : c'est le lien cryptographique entre les deux étapes. On ne peut pas construire un respond valide sans avoir reçu ce token dans la réponse pending. Les deux appels sont cryptographiquement liés, pas seulement séquentiels dans le temps.
Respond. Le back-end vérifie la signature de l'application. Il signe à son tour le résultat. L'application vérifie cette signature avant d'afficher le résultat final.
En résumé, le flux complet ressemble à ceci :
pending · deviceProofToken signé
Back-end
authAttemptProofToken signé Ed25519
✓ vérifié par l'app avant affichage
Back-end
respond · authAttemptProofToken|décision signé
Back-end
Quatre moments de vérification. Aucune étape ne se termine sur une confiance implicite.
06 — Contre quoi ça protège — et les limites honnêtes
Replay. L'authAttemptProofToken est lié à une tentative précise et à usage unique. Rejouer une requête respond passée ne produit aucun résultat : le token est consommé.
Interception (MITM). Un proxy malveillant ne peut pas forger une réponse pending crédible. La clé d'intégration est établie lors de l'inscription — elle ne circule pas dans le flux d'authentification. Aucune réponse non signée par cette clé ne franchit la vérification de l'application.
Énumération. Les tokens d'inscription sont opaques. Il n'existe pas de surface de devinette permettant de sonder l'existence d'un enrollment par essais successifs.
Les limites — documentées en toute transparence.
Le champ devicePrivateKeyStorageTier est une assertion cliente. L'application déclare si sa clé privée bénéficie d'une protection matérielle renforcée. Le back-end enregistre cette déclaration ; il ne peut pas la vérifier cryptographiquement. Un client malveillant pourrait déclarer un niveau de protection qu'il n'a pas. C'est une limite connue, documentée explicitement, pas une faille cachée.
Plus fondamentalement : Ezkey ne fournit pas de chaîne de certification PKI/CA de bout en bout. Le back-end auto-hébergé est l'ancre de confiance par design. Il n'existe pas de tiers de certification indépendant qui valide l'identité du serveur Ezkey auprès de l'appareil via une chaîne de certificats vérifiable par une autorité externe. La confiance dans le back-end repose sur le fait que c'est votre back-end — installé, opéré et contrôlé par votre organisation. C'est un choix de modèle assumé, cohérent avec le principe d'auto-hébergement, et une limite candidate à une évolution future du protocole.
07 — La troisième voie : honnêteté sur ce qu'Ezkey est (et n'est pas)
Il existe aujourd'hui trois grandes approches de l'authentification forte :
Ezkey est Android-first aujourd'hui, avec iOS prévu dans une version future. C'est un projet open source, en développement actif. Être opinionated n'est pas un défaut si les hypothèses de sécurité sont explicitées, documentées et vérifiables. C'est précisément ce que le protocole s'efforce de garantir à chaque étape.
08 — Pour aller plus loin
La solidité du protocole Ezkey ne repose pas sur une promesse — elle repose sur des signatures vérifiables à chaque étape. Chacune peut être auditée indépendamment, avec les bibliothèques cryptographiques standard de la plateforme, sans dépendance à l'outillage Ezkey.
- Article connexe : Ezkey en un coup d'œil — zone de confiance, mobile et flux
English : Same article in English