Études de cas

Comment WhatsApp a adopté les clés d'accès pour offrir une connexion sécurisée et fluide à un milliard d'utilisateurs

Temps de lecture : 8 min

WhatsApp est la plus grande plate-forme de messagerie au monde, utilisée par des milliards d'utilisateurs dans le monde entier. C'est l'outil de communication par défaut pour les personnes de différentes régions, qui connecte les utilisateurs via une messagerie privée, fiable et sécurisée.

"Ce qui me passionne le plus, c'est l'ampleur de l'impact de WhatsApp. Même une petite amélioration de WhatsApp touche des milliards d'utilisateurs dans le monde", explique Mayank Manuja, ingénieur Android au sein de l'équipe chargée de l'inscription et de l'accès à WhatsApp, qui a dirigé la conception et l'implémentation de l'authentification par clé d'accès pour WhatsApp. 

Pour créer une application destinée à une audience de cette ampleur, il faut tenir compte d'un large éventail de conditions réseau, de capacités d'appareils et de niveaux de littératie numérique. Ayant rapidement identifié le potentiel des clés d'accès, WhatsApp s'est engagé à les adopter en 2023, devenant ainsi l'une des premières grandes applications grand public à intégrer cette technologie. En implémentant les clés d'accès, WhatsApp souhaitait proposer une option rapide et résistante à l'hameçonnage qui réduit considérablement les frictions pour les utilisateurs, tout en offrant une protection robuste contre les prises de contrôle de compte et le vol d'identifiants.   

1787852638767.gif
Un utilisateur créant une clé d'accès sur WhatsApp pour se connecter plus rapidement et de manière plus sécurisée.

La décision d'adopter les clés d'accès

Pour WhatsApp, proposer plusieurs méthodes d'accès est essentiel pour permettre aux utilisateurs de rester connectés et de récupérer l'accès à leur compte si nécessaire. Les clés d'accès offrent aux utilisateurs une expérience de connexion simplifiée en un seul geste, qui élimine les risques d'hameçonnage et fonctionne de manière fiable, même dans les régions où la distribution des messages OTP peut être irrégulière. 

En arrière-plan, les clés d'accès utilisent la cryptographie à clé publique-privée pour remplacer la saisie manuelle par une authentification biométrique ou par verrouillage de l'écran. Ce workflow améliore considérablement la vitesse de connexion en réduisant le processus à un seul geste via une interface bottom sheet unifiée qui maintient l'engagement utilisateur dans le contexte de l'application. Les avantages sont doubles : les clés d'accès offrent aux utilisateurs une expérience de connexion simplifiée tout en fournissant une protection native robuste contre les attaques par hameçonnage. Surtout, ils fonctionnent de manière fiable, même dans les régions où l'envoi de mots de passe à usage unique par SMS traditionnel peut être irrégulier.

unnamed.png
Comment les clés d'accès sont enregistrées et utilisées pour l'authentification à l'aide de la cryptographie à clé publique-privée
AANDDM_KARROT_Quote_02.png

En disposant de méthodes d'accès au compte robustes et variées, les utilisateurs ne sont jamais bloqués lorsqu'ils souhaitent accéder à ce qui compte le plus pour eux.

Intégration côté client

Du point de vue des développeurs WhatsApp, l'API Credential Manager a fourni une interface claire et unifiée qui a permis de s'affranchir de la complexité des fournisseurs d'identifiants sous-jacents. Une fois les flux d'intégration initiaux définis, la surface de l'API est devenue simple, la création et la récupération des identifiants suivant des modèles de requête et de réponse bien définis. Vous trouverez le guide d'implémentation dans la documentation pour les développeurs Android. 

Bien que le parcours heureux ait fonctionné dès le départ, la gestion d'une base d'utilisateurs diversifiée sur plusieurs OEM, plusieurs versions d'Android et différentes configurations d'appareils (par exemple, code PIN uniquement par rapport à la biométrie, ou Android 13 par rapport à Android 14 ou version ultérieure) a mis en évidence des cas limites sans précédent. Il s'agissait notamment d'utilisateurs sans verrouillage de l'écran, de types d'exceptions inattendus, de services Play obsolètes et d'un comportement incohérent du fournisseur d'identifiants.

Pour surmonter ces obstacles, les équipes de WhatsApp et de Google ont collaboré étroitement et ont relevé plusieurs défis :

  • Optimisation du flux de recherche d'identifiants : le flux de recherche initial présentait une latence élevée, en particulier pour les utilisateurs qui n'avaient pas encore créé de clé d'accès. Comme la majorité des utilisateurs de WhatsApp se trouvent dans cette catégorie au début, cela a ajouté un délai notable à presque chaque connexion. En instrumentant le chemin d'appel et en identifiant ensemble les goulots d'étranglement, WhatsApp a considérablement accéléré le processus, ce qui a permis d'améliorer les performances et de profiter à l'ensemble de l'écosystème Android.
  • Gestion des états temporaires : WhatsApp a créé une couche complète de gestion des erreurs pour contourner les obstacles spécifiques aux appareils, tels que la disponibilité du gestionnaire de mots de passe, le verrouillage de l'écran non configuré, les problèmes de connectivité intermittents, le matériel incompatible et les services Play obsolètes, en classant les exceptions en états récupérables et terminaux. Cela permettait une dégradation élégante : si un flux de clé d'accès ne pouvait pas aboutir, le système revenait en toute sécurité à l'authentification traditionnelle sans laisser l'utilisateur dans un état d'erreur.
  • Gérer les exceptions spécifiques à l'OS : lorsque la télémétrie a révélé des obstacles spécifiques à certains appareils, comme GetPublicKeyCredentialDomException (Échec du déchiffrement des identifiants) sur certains appareils Android 13 et CreatePublicKeyCredentialDomException (Impossible d'obtenir le compte de synchronisation) lors de la création de clés d'accès sur Android 14, Google et l'équipe WhatsApp ont recherché les causes profondes et ont apporté des améliorations au niveau de la plate-forme pour fluidifier les flux de création. Vous trouverez un guide complet sur les erreurs ici. Il liste les codes d'erreur courants et les descriptions associées à Credential Manager, et fournit des informations sur leurs causes. 
Remarque : Pour en savoir plus, consultez l'article de blog Bonnes pratiques concernant les clés d'accès afin de découvrir comment optimiser l'expérience utilisateur lors de l'adoption des clés d'accès.

Améliorer l'expérience utilisateur

Comme les clés d'accès étaient un concept entièrement nouveau début 2023, il n'existait pas de modèle établi pour inviter à les créer. Grâce à des tests A/B approfondis, WhatsApp a développé un framework contextuel ciblant les utilisateurs qui en bénéficieraient le plus. Cette stratégie a évolué en continu : à mesure que les flux de l'OS Android sont devenus une expérience simplifiée sur un seul écran, WhatsApp a simplifié ses propres invites pour éviter une UI redondante ou déroutante.

Case-Study-1.png
Processus de création de clés d'accès simplifié sur un seul écran de WhatsApp

Architecture côté serveur et obstacles multiplates-formes

Sur le backend, le serveur de WhatsApp implémente les cérémonies WebAuthn/FIDO2 standards. Le backend est écrit en Erlang et appelle la bibliothèque Rust webauthn-rs via une interface native. Cette bibliothèque Rust gère la validation des signatures et l'analyse des identifiants, ce qui permet au code interne de rester concentré sur l'orchestration, le stockage et les règles du produit, telles que l'éligibilité, la limitation du débit et le cycle de vie des identifiants.

L'architecture du serveur orchestre ces cérémonies principales via quatre points d'entrée principaux, associés aux séquences Begin et Finish pour l'enregistrement et l'authentification :

1. Enregistrement de la clé d'accès

Cette séquence gère l'émission des options de création pour le client, la vérification de l'attestation une fois que le client confirme la création, et la persistance sécurisée des identifiants.

unnamed (1).png
Architecture d'interaction entre le serveur et le client lors de l'enregistrement d'une clé d'accès

Erlang : commencer l'enregistrement

begin_registration(UserId) ->
    Existing = list_credentials(UserId),
    %% reuse the existing user handle, or mint a new one
    {UserHandle, IsNew} = user_handle(Existing),
    %% returns the client creation options and the server-side challenge state
    #{client_safe := CreationOptions, server_only := ChallengeState} =
        webauthn:start_registration(UserId, UserHandle, rp_config()),
    %% excludeCredentials: the user's existing credential IDs, so the device won't re-enroll one
    Options = with_exclude_credentials(CreationOptions, credential_ids(Existing)),
    store_challenge(UserId, ChallengeState),          %% short TTL
    IsNew andalso reserve_user_handle(UserId, UserHandle),
    Options.
  • Identifier l'utilisateur : le serveur vérifie d'abord s'il existe des identifiants pour réutiliser un handle utilisateur existant ou en générer un nouveau.
  • Générer des options et un test : il appelle la bibliothèque WebAuthn pour générer les options de création pour le client et un état de test sécurisé pour le serveur.
  • Éviter les doublons : il exclut explicitement les ID d'identifiants existants de l'utilisateur afin que l'appareil ne réenregistre pas accidentellement une clé d'accès déjà enregistrée.
  • Stocker la question d'authentification : le serveur stocke temporairement la question d'authentification avec une valeur TTL (Time To Live) courte et renvoie les options à l'appareil client.

Erlang : terminer l'inscription

finish_registration(UserId, Attestation) ->
    ChallengeState = get_challenge(UserId),          %% must exist and be unexpired
    #{credential_id := CredId, public_key := PubKey} =
        webauthn:finish_registration(Attestation, ChallengeState, rp_config()),
    ok = index_credential(CredId, UserId),            %% map credential_id -> account
    case multi_passkey_enabled(UserId) of
        true  -> add_credential(UserId, CredId, PubKey);      %% append (oldest evicted past the cap)
        false -> replace_credential(UserId, CredId, PubKey)   %% single-passkey mode
    end,
    notify_client(UserId, {passkey_created, CredId}),
    ok.
  • Récupération du challenge : le serveur récupère le challenge stocké, en s'assurant qu'il existe toujours et qu'il n'a pas expiré.
  • Vérifier l'attestation : il transmet la réponse du client (attestation) et la question d'authentification à la bibliothèque WebAuthn pour vérifier la requête et extraire le nouvel ID d'identifiant et la clé publique.
  • Indexation de l'identifiant : le nouvel ID d'identifiant est mappé directement au compte de l'utilisateur pour une recherche rapide ultérieure.
  • Enregistrer et gérer les limites : selon que la fonctionnalité de clés d'accès multiples est activée ou non, le serveur ajoute le nouvel identifiant à la liste de l'utilisateur (en supprimant le plus ancien si une limite est atteinte) ou remplace l'identifiant existant en mode clé d'accès unique.

2. Authentification des identifiants

Comme pour la création, le serveur d'applications gère le flux d'authentification en orchestrant la séquence de connexion. Cela inclut la vérification de l'assertion après l'authentification du client et la mise à jour dynamique des identifiants stockés chaque fois que WebAuthn signale qu'une actualisation est nécessaire.

Erlang : commencer l'authentification

begin_authentication(UserId) ->
    Credentials = list_valid_credentials(UserId),
    #{client_safe := RequestOptions, server_only := ChallengeState} =
        webauthn:start_authentication(Credentials, rp_config()),
    store_challenge(UserId, ChallengeState),          %% short TTL
    RequestOptions.
  • Récupérer les identifiants valides : le serveur recherche tous les identifiants actuellement valides associés à l'utilisateur.
  • Générer un test : il utilise ces identifiants pour créer des options de requête pour le client et génère un nouveau test côté serveur.
  • Stockage et renvoi : comme lors de l'enregistrement, la question d'authentification est enregistrée temporairement, et les options de requête sont transmises à l'application cliente.

Erlang : terminer l'authentification

finish_authentication(UserId, Assertion) ->
    ChallengeState = get_challenge(UserId),
    Credentials = list_valid_credentials(UserId),
    case webauthn:finish_authentication(Credentials, Assertion, ChallengeState) of
        #{user_verified := true, credential_id := CredId, needs_update := NeedsUpdate} = Result ->
            %% webauthn tells us when the stored credential should be refreshed
            NeedsUpdate andalso refresh_credential(UserId, CredId, Result),
            mark_credential_used(UserId, CredId),
            {ok, CredId};
        _ ->
            {error, not_allowed}
    end.
  • Vérifier l'assertion : le serveur récupère le test et les identifiants valides stockés, puis demande à la bibliothèque WebAuthn de vérifier l'assertion du client.
  • Actualiser si nécessaire : si l'utilisateur est validé, le serveur vérifie l'indicateur needs_update. La bibliothèque WebAuthn utilise cet indicateur pour signaler si l'état des identifiants stockés doit être actualisé sur le serveur.
  • Finalisation : le serveur marque l'identifiant comme utilisé et termine le processus de connexion.
Case-Study-2.png
Procédure de connexion par clé d'accès dans l'application WhatsApp

Pour en savoir plus sur l'enregistrement du serveur, suivez le guide d'intégration ici. 

Considérations architecturales avancées 

L'implémentation des clés d'accès sur le serveur à grande échelle a présenté des défis uniques, en particulier en ce qui concerne l'architecture des comptes et la synchronisation des appareils. Ashish Choudhary, de l'équipe backend de WhatsApp, a souligné les principaux obstacles auxquels ils ont été confrontés :

  1. Migration vers plusieurs clés d'accès par compte : l'ancienne logique de serveur de WhatsApp était étroitement liée à l'hypothèse d'un seul identifiant par utilisateur. Pour s'adapter aux réalités modernes du multi-appareil, ils ont conçu un système de liste limitée qui supprime intelligemment les identifiants les plus anciens une fois la limite atteinte. Pour garantir une stabilité absolue, ce changement structurel majeur a été déployé progressivement par le biais de tests rigoureux.
  2. Équilibrer le cycle de vie des identifiants : la gestion de la validité des identifiants nécessitait une approche délicate. Si vous invalidez les identifiants de manière trop agressive, vous risquez de forcer des réenregistrements inutiles. En revanche, si vous êtes trop indulgent, les identifiants obsolètes s'accumuleront. WhatsApp a résolu ce problème en implémentant des états de cycle de vie équilibrés pour maintenir une sécurité stricte sans frustrer les utilisateurs, complétés par un nettoyage automatique en arrière-plan des clés d'accès inactives.

Repenser la synchronisation multi-appareil

Cette architecture robuste à clés d'accès multiples a également permis à WhatsApp de repenser complètement l'ergonomie multiplate-forme. Le flux multi-appareil WebAuthn standard nécessite de scanner un QR code sur un appareil et de s'authentifier via Bluetooth sur un autre. Cependant, WhatsApp a constaté que la dépendance au Bluetooth n'était pas fiable et que les utilisateurs confondaient souvent les nouveaux QR codes avec le processus d'association existant de WhatsApp Web.

Au lieu d'imposer un mécanisme de transport fragile entre les appareils, WhatsApp permet aux utilisateurs de conserver leurs clés d'accès de manière native dans plusieurs écosystèmes, comme le Gestionnaire de mots de passe de Google sur Android et le trousseau iCloud sur iOS. Lorsqu'ils migrent vers une nouvelle plate-forme, il leur suffit de générer une nouvelle clé d'accès lors de leur prochaine connexion. Cette approche est totalement transparente pour l'utilisateur et fonctionne de manière fluide sur la nouvelle infrastructure de serveur multi-clés d'accès.

Cap sur la suite

Depuis le lancement des clés d'accès, WhatsApp a constaté une forte adoption naturelle de la part de sa vaste base d'utilisateurs. En transformant le processus de connexion traditionnel en plusieurs étapes en un seul geste biométrique fluide, l'application a considérablement amélioré l'expérience utilisateur. Fort de cet élan, WhatsApp étend désormais l'utilité des clés d'accès au-delà des connexions initiales, en explorant la réauthentification fluide dans l'application pour les actions sensibles sur le compte, comme les sauvegardes chiffrées par clé d'accès.

WhatsApp collabore activement avec des plates-formes partenaires pour mettre au point des parcours de création d'identifiants plus fluides, en anticipant que les obstacles à l'adoption diminueront naturellement à mesure que les capacités biométriques des appareils se développeront. 

Recommandation pour les développeurs qui créent des applications à grande échelle

Pour les développeurs qui se préparent à intégrer les clés d'accès à grande échelle, l'équipe WhatsApp partage ces recommandations essentielles :

  • Investissez rapidement dans une taxonomie des erreurs : classez les nombreuses exceptions de Credential Manager en états récupérables ou terminaux, et définissez des chemins de remplacement clairs et appropriés pour chaque scénario.
  • Comprendre votre entonnoir d'éligibilité : instrumentez les vérifications des fonctionnalités de l'appareil, telles que la présence d'un verrouillage de l'écran, du matériel biométrique et des versions des services Play, et concevez des flux pour exclure de manière proactive les utilisateurs non éligibles plutôt que d'échouer en cours de flux.
  • Préparez votre application à une solution de remplacement : utilisez les clés d'accès comme méthode d'authentification principale optimale pour les appareils compatibles, mais conservez toujours les méthodes traditionnelles comme solution de remplacement fiable et universelle.
  • Planifiez la fragmentation des versions d'OS : le comportement des clés d'accès peut varier d'un système d'exploitation à l'autre. Testez minutieusement sur Android 13, 14 et 15+, et tenez compte des variations spécifiques aux OEM dans l'interface utilisateur de sélection des identifiants.
  • Proposez des ventes incitatives de manière contextuelle et informez les utilisateurs : présentez la création de clés d'accès de manière naturelle lors d'actions liées à la sécurité. Mettez clairement en avant la proposition de valeur (vitesse et sécurité) en utilisant un langage accessible pour favoriser l'adoption par les utilisateurs.
  • Surveillez de manière proactive : l'écosystème évolue à chaque mise à jour de l'OS. Suivez en continu les schémas de latence et d'erreur pour garder une longueur d'avance sur l'évolution des appareils.
AANDDM_Passkeys_Quote_01.png

Premiers pas avec les clés d'accès et Credential Manager

Familiarisez-vous avec les clés d'accès et Credential Manager sur Android à l'aide de notre guide d'intégration et de notre exemple de code public.

Si vous avez des questions ou des problèmes, vous pouvez nous en faire part via l'outil de suivi des problèmes liés aux identifiants Android.

Written by:
Continuer la lecture