Lors du devfest 2024 à Nantes, j'ai eu la chance d'assister à une conférence sur les passkeys animée par Milica Mihajlija. Elle a parlé des avantages apportés par ce nouveau système de connexion.
- Notamment le fait que le passkey n'est pas stocké sur un serveur, fini les fuites de mot de passe.
- Ou encore un passkey généré pour un site ne peut pas être utilisé pour un autre site, impossible donc de se faire avoir par une page de phishing qui usurperait l'identité d'un vrai site.
Pendant ce talk, elle a parlé de l'implémentation côté frontend, mais elle n'a pas eu le temps d'aborder le côté backend de la solution.
Alors est-ce que c'est compliqué ? Regardons ce schéma pour mieux comprendre.

Pendant la conférence, on avait vu que les passkeys reposent sur un échange de clés asymétriques, clé privée et clé publique. La paire de clé est créée dans le navigateur du client via l'API WebAuthn.
credentials.create(challenge)
Cette méthode prend en paramètre un challenge.
Un challenge est une donnée qui protège les utilisateurs des attaques par rejeu. Lorsqu'une question d'authentification s'affiche, le fournisseur de la clé d'accès la signe pour prouver que l'utilisateur détient la clé d'accès au moment de la requête d'authentification. Si un pirate informatique intercepte une requête d'authentification et tente de la rejouer pour s'authentifier à la place de l'utilisateur, l'opération échoue, car le serveur détecte une non-concordance des questions d'authentification.
Il faut donc implémenter côté serveur une API qui puisse fournir ce challenge. D'après la documentation officielle ce n'est pas une chose simple à réaliser il est donc fortement conseillé d'utiliser une librairie qui implémente le standard WebAuthn. Il en existe plein, en java, deux libraires ont retenu mon attention.
- https://github.com/Yubico/java-webauthn-server
- https://github.com/webauthn4j/webauthn4j-spring-security
C'est cette dernière que j'ai utilisé, elle ajoute un endpoint /webauthn/ qui gère toutes les opérations lié à l'authentification, dont la création du challenge.
const optionsRes = await fetch("/webauthn/attestation/options");
const options = await optionsRes.json();
C'est ce challenge qui va permettre la création de la clé privée qui sera stockée côté navigateur et la clé publique qui sera envoyée à notre backend pour être stockée.
Une fois que l'utilisateur a créé ses clés, à la prochaine connexion, il demandera un nouveau challenge qu'il signera avec sa clé privé. Notre serveur vérifiera l'authenticité de la demande grâce à la clé publique enregistrée sur le serveur.
La gestion de l'authentification est déléguée à l'api webauthn, on voit bien que cela rend sa mise en place très facile. Vous n'avez donc plus d'excuse pour ne pas proposer cette méthode d'authentification sur vos projets. Les entreprises qui implémentent les passkeys peuvent aussi réduire les coûts de support liés à la gestion des mots de passe et renforcer la confiance des utilisateurs. Des secteurs comme la finance ou le e-commerce peuvent particulièrement en tirer profit, en réduisant l’abandon de panier et en offrant une expérience d'authentification plus fluide et sécurisée.
Sources :