py_webauthn (le paquet webauthn sur PyPI) génère les options d’enregistrement et d’authentification et vérifie les réponses, tous formats d’attestation compris, en s’appuyant sur pyca/cryptography. Les essais lui ont fourni le même enregistrement et les mêmes assertions, issus d’un authentificateur logiciel, que pour SimpleWebAuthn, go-webauthn et WebAuthn4J, ce qui fait ressortir les différences entre elles.
Ses politiques par défaut sont les plus permissives des quatre. generate_registration_options() n’envoie aucun membre authenticatorSelection, si bien que les navigateurs se rabattent sur la vérification de l’utilisateur preferred et les clés résidentes discouraged (des clés d’accès non détectables), et verify_registration_response() et verify_authentication_response() ont accepté des réponses dont l’indicateur UV n’était pas positionné, sauf si require_user_verification=True est passé. Une connexion construite sur les valeurs par défaut accepte donc un simple appui sur une clé de sécurité, sans PIN. Définissez explicitement la politique des deux côtés, comme le fait l’exemple.
Les signatures d’assertion doivent être en ASN.1 DER : une signature r‖s brute de 64 octets a échoué avec Could not verify authentication signature, un message qui ne mentionne pas l’encodage ; le convertisseur DER ⇄ brut indique si un client de test a produit la mauvaise forme. Une signature DER high-S a été vérifiée. Ed25519 (-8), ES256 (-7) et RS256 (-257) sont proposés par défaut ; il n’y a pas d’entrée ML-DSA, contrairement à SimpleWebAuthn 14.
Les compteurs sont stricts : Response sign count of 3 was not greater than current count of 5, même erreur pour 0 après 5, tandis que 0 après 0 (ce que renvoient les clés d’accès synchronisées) a été vérifié. Enregistrez le new_sign_count renvoyé après chaque connexion réussie.
Décodez la sortie brute du navigateur avec l’inspecteur WebAuthn et expérimentez sans risque dans le bac à sable des clés d’accès.