Qu'est-ce que WebAuthn et que sont les passkeys ?
La connexion sans mot de passe par cryptographie à clé publique : comment un navigateur et un authentificateur prouvent l'identité de l'utilisateur sans jamais partager de secret.
- Nom complet
- Web Authentication (WebAuthn)
- Publié par
- W3C, avec la FIDO Alliance, 2019
- Repose sur
- Cryptographie à clé publique, protocole CTAP (FIDO2)
- Dans TOSIAM
- Nœuds de graphe passkeys et modules WebAuthn
Sur cette page
WebAuthn et les passkeys en bref#
WebAuthn (Web Authentication) est une API standard des navigateurs qui permet à un site de connecter ses utilisateurs avec une paire de clés cryptographiques plutôt qu’avec un mot de passe. La clé privée reste sur un appareil de l’utilisateur ; le site ne conserve que la clé publique.
Une passkey (en français, « clé d’accès ») est le nom grand public de ce mécanisme. Quand un site vous propose de « créer une clé d’accès », puis que vous vous connectez ensuite avec votre empreinte, votre visage ou le code de votre téléphone, c’est WebAuthn qui travaille.
WebAuthn est publié par le W3C et forme, avec le protocole CTAP de la FIDO Alliance, l’ensemble appelé FIDO2. WebAuthn décrit le dialogue entre le site et le navigateur ; CTAP décrit le dialogue entre le navigateur et un authentificateur externe, comme une clé USB ou un téléphone.
Pourquoi WebAuthn existe#
Le mot de passe cumule les faiblesses : il se devine, se réutilise d’un site à l’autre, fuit lors d’une compromission de base de données et se laisse saisir sur un faux site. Ajouter un code à usage unique (TOTP, SMS) limite les dégâts, mais ne règle pas le dernier point : un site d’hameçonnage bien fait peut demander le mot de passe et le code, puis les rejouer aussitôt sur le vrai site.
WebAuthn change la nature de la preuve :
- aucun secret partagé : le serveur ne stocke qu’une clé publique, inutilisable par un attaquant qui la volerait ;
- une clé par site : chaque justificatif est lié à un domaine précis, il n’y a donc rien à réutiliser ailleurs ;
- résistance à l’hameçonnage : le navigateur indique lui-même l’origine réelle de la page, et l’authentificateur refuse de signer pour un autre domaine que celui du justificatif.
Les acteurs#
| Rôle | Nom WebAuthn | Exemple |
|---|---|---|
| Le site qui veut authentifier l’utilisateur | Partie de confiance (Relying Party, RP) | TOSIAM, sur login.example.fr |
| Le logiciel qui relaie les échanges | Client | Le navigateur |
| Le composant qui détient la clé privée | Authentificateur (authenticator) | Windows Hello, Touch ID, un téléphone Android, une clé de sécurité USB |
On distingue deux familles d’authentificateurs :
- les authentificateurs de plateforme, intégrés à l’appareil (lecteur d’empreinte d’un ordinateur portable, puce sécurisée d’un téléphone) ;
- les authentificateurs itinérants (roaming), qui se branchent ou se connectent à plusieurs appareils : clé USB ou NFC, téléphone utilisé via un QR code et Bluetooth.
Passkey, clé de sécurité et justificatif découvrable#
Le vocabulaire varie selon les sources ; quelques repères suffisent.
Un justificatif (public key credential) est la paire de clés créée pour un site et un compte. Il porte un identifiant (credential ID) que le serveur enregistre avec la clé publique.
Un justificatif est découvrable (discoverable credential, anciennement resident key) quand l’authentificateur le conserve avec l’identifiant de l’utilisateur. Le site peut alors lancer l’authentification sans demander d’abord le nom d’utilisateur : l’authentificateur propose les comptes qu’il connaît pour ce domaine. C’est ce qui permet une connexion « sans identifiant ».
Une passkey est, au sens de la FIDO Alliance, un justificatif découvrable. Elle peut être :
- synchronisée entre les appareils d’un même utilisateur par le gestionnaire de mots de passe de la plateforme (trousseau iCloud, gestionnaire Google, etc.), ce qui évite de la perdre avec un appareil ;
- liée à un appareil, comme sur une clé de sécurité matérielle, d’où elle ne peut pas sortir.
L’enregistrement#
L’enregistrement (la « cérémonie d’enregistrement » dans la spécification) crée le justificatif et transmet la clé publique au serveur. L’utilisateur est généralement déjà connecté, par exemple avec son mot de passe.
- Utilisateur vers Navigateur Demande l’ajout d’une passkey
- Navigateur vers TOSIAM Transmet la demande
-
TOSIAM vers Navigateur
Envoie les options :
rp,user,challenge, algorithmes -
Navigateur vers Authentificateur
Appelle
navigator.credentials.create() - Authentificateur vers Utilisateur Demande un geste : empreinte, visage ou code PIN
- Utilisateur vers Authentificateur Confirme
-
Authentificateur
Crée une paire de clés liée à
login.example.fr - Authentificateur vers Navigateur Renvoie la clé publique et l’identifiant du justificatif
-
Navigateur vers TOSIAM
Transmet
attestationObjectetclientDataJSON - TOSIAM Vérifie défi, origine et domaine, puis enregistre la clé publique
Les options envoyées au navigateur ressemblent à ceci :
{
"rp": { "id": "login.example.fr", "name": "TOSIAM" },
"user": {
"id": "Y2xhaXJlLm1hcnRpbg",
"name": "claire.martin",
"displayName": "claire.martin"
},
"challenge": "q3Vt1w6zS0bJ2mB8yQx4n7ZkR5aP9cLdEfGhIjKlMnO",
"pubKeyCredParams": [
{ "type": "public-key", "alg": -7 },
{ "type": "public-key", "alg": -257 }
],
"timeout": 60000,
"authenticatorSelection": {
"residentKey": "required",
"requireResidentKey": true,
"userVerification": "required"
},
"attestation": "none"
}| Champ | Signification |
|---|---|
rp.id | L’identifiant de la partie de confiance : un domaine égal à celui de la page, ou l’un de ses domaines parents. Le justificatif y sera lié. |
user.id | Un identifiant opaque de l’utilisateur, que l’authentificateur restituera lors des connexions sans identifiant (userHandle). |
challenge | Une valeur aléatoire à usage unique, que le serveur retrouvera dans la réponse. |
pubKeyCredParams | Les algorithmes acceptés, par ordre de préférence, sous forme de codes COSE : -7 pour ES256 (ECDSA P-256), -257 pour RS256. |
authenticatorSelection | Les exigences : justificatif découvrable ou non, vérification de l’utilisateur. requireResidentKey est l’ancienne forme de residentKey, gardée pour les navigateurs anciens. |
attestation | Le souhait de recevoir une preuve de l’origine de l’authentificateur (voir plus bas). |
En retour, le serveur vérifie que clientDataJSON contient le type webauthn.create, le bon défi et la bonne origine, que les données de l’authentificateur portent l’empreinte SHA-256 du rp.id attendu, puis il enregistre l’identifiant du justificatif et sa clé publique.
L’authentification#
À chaque connexion, le serveur envoie un nouveau défi, et l’authentificateur le signe avec la clé privée.
- Utilisateur vers Navigateur Choisit « Se connecter avec une passkey »
-
TOSIAM vers Navigateur
Envoie un
challengeet lerpId -
Navigateur vers Authentificateur
Appelle
navigator.credentials.get() - Authentificateur vers Utilisateur Demande le geste de déverrouillage
- Utilisateur vers Authentificateur Confirme
- Authentificateur Signe les données d’authentification et le défi
-
Authentificateur vers Navigateur
Renvoie signature,
authenticatorDataetuserHandle -
Navigateur vers TOSIAM
Transmet la réponse et
clientDataJSON - TOSIAM Vérifie la signature avec la clé publique enregistrée
La signature porte sur la concaténation de authenticatorData et de l’empreinte SHA-256 de clientDataJSON. Le serveur contrôle le type webauthn.get, le défi, l’origine, l’empreinte du rpId, les indicateurs de présence et de vérification, puis la signature elle-même.
Si le justificatif est découvrable, le serveur peut envoyer une liste allowCredentials vide : l’authentificateur choisit le compte et renvoie son user.id dans userHandle, ce qui suffit à identifier l’utilisateur. Sinon, le serveur demande d’abord l’identifiant, puis liste les justificatifs de ce compte.
Les navigateurs récents proposent aussi la médiation conditionnelle (mediation: "conditional") : la demande part en arrière-plan dès l’affichage de la page, et les passkeys disponibles apparaissent dans les suggestions de saisie automatique du champ identifiant, à côté des mots de passe enregistrés.
Ce que le serveur vérifie, et pourquoi#
L’origine et le domaine. Le navigateur écrit dans clientDataJSON l’origine réelle de la page, que le site ne peut pas falsifier. L’authentificateur, lui, n’utilise un justificatif que pour le rpId auquel il est lié. Une page d’hameçonnage sur un autre domaine ne peut donc ni utiliser la passkey, ni produire une réponse que le vrai serveur accepterait.
La présence et la vérification de l’utilisateur. Deux indicateurs figurent dans authenticatorData. UP (user present) atteste qu’une personne a fait un geste, par exemple toucher la clé. UV (user verified) atteste que l’authentificateur a vérifié l’identité de cette personne, par biométrie ou code PIN. Avec UV, une passkey vaut à elle seule deux facteurs : l’appareil possédé et le geste qui le déverrouille.
L’attestation. Lors de l’enregistrement, l’authentificateur peut joindre une déclaration signée par son fabricant, qui prouve son modèle (identifié par un AAGUID). Le serveur peut la vérifier grâce au FIDO Metadata Service (MDS), un catalogue publié par la FIDO Alliance, et n’accepter par exemple que certaines clés certifiées. Les valeurs possibles de attestation sont none, indirect, direct et enterprise. La plupart des services grand public demandent none : l’attestation sert surtout aux organisations qui imposent un matériel précis.
Le compteur de signatures. Un authentificateur peut incrémenter un compteur à chaque utilisation. Un compteur qui recule trahit un possible clonage. Les passkeys synchronisées renvoient souvent 0, faute de compteur partagé entre appareils.
Bonnes pratiques#
- Servez les pages en HTTPS : WebAuthn n’est disponible que dans un contexte sécurisé (
https://, ouhttp://localhostpour le développement). - Choisissez le
rpIdavec soin. Il ne peut plus changer sans réenregistrer toutes les passkeys ; un domaine parent commeexample.frpermet de les utiliser sur plusieurs sous-domaines. - Générez un défi aléatoire par cérémonie, conservez-le côté serveur et n’acceptez qu’une seule réponse.
- Exigez la vérification de l’utilisateur (
userVerification: "required") si la passkey doit remplacer le mot de passe et le second facteur. - Permettez l’enregistrement de plusieurs passkeys par compte, et prévoyez une procédure de récupération en cas de perte d’appareil.
- Gardez une méthode de repli pour les navigateurs ou postes qui n’autorisent pas WebAuthn.
WebAuthn et les passkeys dans TOSIAM#
TOSIAM est une partie de confiance WebAuthn. Les passkeys s’utilisent dans un graphe d’authentification grâce à cinq nœuds, détaillés dans Nœuds : Passkeys / WebAuthn.
Enregistrement. PasskeyRegistrationNode enregistre une passkey pour l’utilisateur en cours d’authentification. Il se configure avec un rpId, un nom affiché (rpName, TOSIAM par défaut) et l’origine attendue (origin), qui doit correspondre exactement. Les options qu’il envoie sont celles de l’exemple ci-dessus : justificatif découvrable exigé, vérification de l’utilisateur exigée, attestation none, algorithmes ES256 et RS256, délai de 60 secondes et défi aléatoire de 32 octets. Le user.id est l’identifiant de l’utilisateur encodé en base64url. PasskeyEnrollmentCheckNode indique en amont si l’utilisateur possède déjà au moins une passkey (sorties enrolled et notEnrolled).
Authentification. PasskeyAuthenticationNode authentifie un utilisateur déjà identifié dans le graphe, par exemple après un nœud de saisie de l’identifiant. Il envoie la liste des justificatifs de ce compte, vérifie le type, le défi, l’origine, l’empreinte du rpId, les indicateurs UP et UV et la signature. Sa sortie unsupported est prise quand le navigateur ne prend pas en charge WebAuthn : reliez-la à un autre facteur, comme un code TOTP.
Connexion sans identifiant. PasskeyConditionalAuthenticationNode met en œuvre la médiation conditionnelle. Placé avec le nœud de saisie de l’identifiant dans une même page, il envoie un défi sans allowCredentials ; si l’utilisateur choisit une passkey dans les suggestions, le nœud retrouve le compte à partir du userHandle et l’authentifie. S’il saisit son identifiant normalement, le nœud s’efface. PasskeyConditionalDecisionNode, placé juste après la page, oriente ensuite le parcours selon qu’une passkey a déjà été utilisée ou non. L’interface de connexion de TOSIAM affiche aussi un bouton pour ouvrir directement le sélecteur de passkeys du navigateur.
Compteur de signatures. TOSIAM met à jour le compteur après chaque authentification réussie. Un compteur qui recule est journalisé comme un possible clonage, sans bloquer la connexion, pour ne pas pénaliser les passkeys synchronisées.
Stockage. Les justificatifs sont enregistrés dans l’annuaire LDAP, dans des entrées dédiées reliées au compte par son identifiant unique (entryUUID par exemple). Le service WebAuthn Authenticator doit être configuré dans le royaume pour cela. Les passkeys d’un utilisateur se consultent et se suppriment par l’API REST, sur /realms/{realm}/users/{user}/devices/webauthn.
Modules legacy. Pour les chaînes d’authentification existantes, les modules WebAuthn (Register) et WebAuthn (Authenticate), fondés sur la bibliothèque WebAuthn4J, restent disponibles ; le tutoriel FIDO2 les décrit. Ils rendent configurables le justificatif découvrable, la vérification de l’utilisateur et l’attestation (none par défaut, direct ou indirect). En mode direct, l’attestation est vérifiée à partir des métadonnées du FIDO MDS et de métadonnées ajoutées par l’administrateur, ce qui permet de restreindre les modèles d’authentificateurs acceptés.
Pour aller plus loin#
- Web Authentication Level 2, la recommandation du W3C
- Web Authentication Level 3, la version en cours d’élaboration
- Passkeys, la présentation de la FIDO Alliance
- FIDO Metadata Service
Mis à jour le