Aller au contenu
ecdsa.com
Go

go-webauthn

go-webauthn, la bibliothèque de partie de confiance WebAuthn pour Go : signatures d’assertion DER uniquement, vérification de l’utilisateur pilotée par la session, et régressions du compteur signalées par un avertissement de clonage au lieu d’un échec de connexion.
Licence
BSD-3-Clause
Version vérifiée
0.18.2 ·
Code source
github.com/go-webauthn/webauthn
Documentation
pkg.go.dev/github.com/go-webauthn/webauthn/webauthn

Compatibilité en un coup d’œil

WebAuthn

github.com/go-webauthn/webauthn (le fork maintenu de duo-labs/webauthn) prend en charge les deux cérémonies (BeginRegistration/FinishRegistration et BeginLogin/FinishLogin, ou leurs variantes Validate* pour les frameworks autres que net/http) et vérifie tous les formats d’attestation. Les essais ont validé les mêmes réponses d’authentificateur logiciel que pour SimpleWebAuthn, py_webauthn et WebAuthn4J.

La politique vient de la configuration et elle est transportée dans SessionData. Avec un AuthenticatorSelection vide, BeginRegistration a envoyé un objet vide, si bien que les navigateurs appliquent les valeurs par défaut (vérification de l’utilisateur preferred, clé résidente discouraged), et la validation a accepté des réponses dont l’indicateur UV n’était pas positionné, car la session ne demandait que preferred. Avec UserVerification: required dans la session, la même assertion a échoué avec User verification required but flag not set by authenticator. Définissez la politique dans Config.AuthenticatorSelection, comme le fait l’exemple, et conservez l’intégralité de SessionData entre les deux appels.

La gestion du compteur est la principale différence avec les autres bibliothèques. Une assertion dont le compteur (3) était inférieur à la valeur enregistrée (5) a permis de se connecter : l’identifiant renvoyé avait Authenticator.CloneWarning positionné et son SignCount laissé à 5. La bibliothèque se contente de signaler un clonage possible ; refuser ou non la connexion relève de votre code, qui doit contrôler CloneWarning après chaque connexion.

Les signatures d’assertion doivent être en ASN.1 DER (une signature r‖s brute de 64 octets a échoué avec Error validating the assertion signature: Signature invalid or not provided), et une signature DER high-S a été vérifiée. La liste pubKeyCredParams par défaut est longue : ES256, ES384 et ES512 (-7, -35, -36), RS256 à RS512 (-257 à -259), PS256 à PS512 (-37 à -39) et Ed25519 (-8) ; l’identifiant Ed25519 a été vérifié de bout en bout. La 0.18.2 ne comporte aucune entrée ML-DSA.

Décodez ce qu’envoie un navigateur avec l’inspecteur WebAuthn, identifiez les modèles d’authentificateurs avec la recherche d’AAGUID et essayez les cérémonies dans le bac à sable des clés d’accès.

Les faits et les vérifications qui les fondent

Rien de ce qui suit n’est copié d’une documentation. La vérification content/libraries/verify/go-webauthn/run.sh a exécuté go-webauthn 0.18.2 dans l’image de conteneur golang:1.27.3-trixie le 20 octobre 2026 ; la page doit correspondre à ce que la vérification a affiché, et chaque fait cite les lignes en question.

  • Algorithmes COSE par défaut

    -7-35-36-257-258-259-37-38-39-8

    BeginRegistration liste les algorithmes COSE -7, -35, -36 (ES256/384/512), -257, -258, -259 (RS256/384/512), -37, -38, -39 (PS256/384/512) et -8 (Ed25519).

    Relevé par la vérification
    fact webauthn-default-algorithms = -7, -35, -36, -257, -258, -259, -37, -38, -39, -8
  • Attestation par défaut

    none

    La transmission de l’attestation vaut none par défaut.

    Relevé par la vérification
    fact webauthn-attestation = none
  • Vérification de l’utilisateur par défaut

    preferred

    authenticatorSelection est envoyé par défaut sous forme d’objet vide : le navigateur applique donc preferred.

    Relevé par la vérification
    fact webauthn-user-verification = preferred
    evidence webauthn-user-verification: authenticatorSelection in BeginRegistration output: {}
  • Clé résidente par défaut

    discouraged

    Sans residentKey dans les options, c’est la valeur par défaut de WebAuthn, discouraged, qui s’applique.

    Relevé par la vérification
    fact webauthn-resident-key = discouraged
  • Vérification de l’utilisateur exigée par défaut

    no

    Avec la vérification de l’utilisateur de la session à preferred, un enregistrement et une assertion où seul UP était positionné ont été vérifiés ; avec required, l’assertion a échoué avec User verification required but flag not set by authenticator.

    Relevé par la vérification
    fact webauthn-uv-enforced-by-default = no
    evidence webauthn-uv-enforced-by-default: registration with the UV flag clear, session UV preferred: verified
  • Encodage de la signature d’assertion

    der

    Une assertion ES256 correcte avec une signature DER a été vérifiée.

    Relevé par la vérification
    fact webauthn-assertion-encoding = der
  • Signature d’assertion r‖s brute

    rejected

    Une signature r‖s brute de 64 octets a échoué avec Error validating the assertion signature: Signature invalid or not provided.

    Relevé par la vérification
    fact webauthn-raw-signature = rejected
  • Signature d’assertion high-S

    accepted

    Une signature DER dont s a été remplacé par n − s a été vérifiée.

    Relevé par la vérification
    fact webauthn-high-s = accepted
  • Compteur de signatures qui recule

    flagged

    Un compteur à 3 après une valeur enregistrée de 5 n’a pas fait échouer la connexion : l’identifiant est revenu avec CloneWarning à true et SignCount toujours à 5.

    Relevé par la vérification
    fact webauthn-counter-regression = flagged
    evidence webauthn-counter-regression: counter 3 after a stored 5: login succeeded, CloneWarning true, SignCount now 5
    evidence webauthn-counter-regression: counter 0 after a stored 0: verified, CloneWarning false
  • Identifiants Ed25519

    supported

    Un identifiant Ed25519 (COSE -8) a été enregistré et authentifié avec succès.

    Relevé par la vérification
    fact webauthn-ed25519 = supported
    evidence webauthn-ed25519: verified

Utilisation

Configurer la partie de confiance pour exiger la vérification de l’utilisateur et des identifiants détectables, et retrouver la politique dans les options et dans la session.
package main

import (
	"fmt"

	"github.com/go-webauthn/webauthn/protocol"
	"github.com/go-webauthn/webauthn/webauthn"
)

type user struct{}

func (user) WebAuthnID() []byte                         { return []byte("user-1") }
func (user) WebAuthnName() string                       { return "user@example.com" }
func (user) WebAuthnDisplayName() string                { return "User" }
func (user) WebAuthnCredentials() []webauthn.Credential { return nil }

func main() {
	w, _ := webauthn.New(&webauthn.Config{
		RPID: "example.com", RPDisplayName: "Example", RPOrigins: []string{"https://example.com"},
		// Without this, options say nothing about UV or discoverable credentials.
		AuthenticatorSelection: protocol.AuthenticatorSelection{
			ResidentKey: protocol.ResidentKeyRequirementRequired, UserVerification: protocol.VerificationRequired,
		},
	})
	creation, session, _ := w.BeginRegistration(user{})
	// The session carries the requirement into FinishRegistration/FinishLogin.
	fmt.Println("uv:", creation.Response.AuthenticatorSelection.UserVerification, session.UserVerification)
	fmt.Println("resident key:", creation.Response.AuthenticatorSelection.ResidentKey)
}

Le banc de test des extraits de code exécute chaque exemple tel quel dans l’image de conteneur golang:1.27.3-trixie, et l’exécution échoue si la sortie ne correspond pas.

Commande
GOFLAGS=-mod=mod go run .
La sortie doit correspondre à cette expression régulière
uv: required required\nresident key: required

Bibliothèques