本文へスキップ
ecdsa.com
Go

go-webauthn

go-webauthn は、Go 向けの WebAuthn リライングパーティライブラリです。アサーション署名は DER のみ、ユーザー検証の要否はセッションで決まり、カウンターの巻き戻りはログインの失敗ではなくクローンの警告として報告されます。
ライセンス
BSD-3-Clause
確認したバージョン
0.18.2 ·
ソースコード
github.com/go-webauthn/webauthn
ドキュメント
pkg.go.dev/github.com/go-webauthn/webauthn/webauthn

互換性の概要

WebAuthn

github.com/go-webauthn/webauthn(duo-labs/webauthn の保守されているフォーク)は、両方のセレモニー(BeginRegistration/FinishRegistration と BeginLogin/FinishLogin、または net/http 以外のフレームワーク向けの Validate* 系の関数)を実行し、あらゆる形式のアテステーションを検証します。チェックでは、SimpleWebAuthn、py_webauthn、WebAuthn4J と同じソフトウェア認証器のレスポンスを検証しました。

ポリシーは設定から取得され、SessionData に保持されます。AuthenticatorSelection が空のとき、BeginRegistration は空のオブジェクトを送信したため、ブラウザーはデフォルト値(ユーザー検証は preferred、レジデントキーは discouraged)を適用しました。セッションが preferred しか要求していなかったため、検証では UV フラグが立っていないレスポンスも受け入れられました。セッションに UserVerification: required を設定すると、同じアサーションは User verification required but flag not set by authenticator で失敗しました。サンプルのように Config.AuthenticatorSelection でポリシーを設定し、2 つの呼び出しの間で SessionData 全体を保存してください。

カウンターの扱いが、他のライブラリとの最も重要な違いです。カウンター(3)が保存済みの値(5)より小さいアサーションでも、ログインに成功しました。返された認証情報では Authenticator.CloneWarning が設定され、SignCount は 5 のままでした。このライブラリはクローンの可能性を報告するだけで、ログインを拒否するかどうかはアプリケーションのコード次第です。そのコードは、ログインのたびに CloneWarning を確認しなければなりません。

アサーション署名は ASN.1 DER でなければなりません(64 バイトの生の r‖s 署名は Error validating the assertion signature: Signature invalid or not provided で失敗しました)。また、high-S の DER 署名は検証を通りました。デフォルトの pubKeyCredParams の一覧は長く、ES256、ES384、ES512(-7、-35、-36)、RS256〜RS512(-257〜-259)、PS256〜PS512(-37〜-39)、Ed25519(-8)が含まれます。Ed25519 の認証情報は、登録から認証まで一通り検証できました。0.18.2 には ML-DSA の項目はありません。

ブラウザーが送信する内容は WebAuthn インスペクターでデコードし、認証器の機種は AAGUID 検索で調べ、セレモニーはパスキーサンドボックスで試してください。

事実とその根拠となるチェック

以下の内容はドキュメントからの転記ではありません。2026年10月20日に、チェック content/libraries/verify/go-webauthn/run.sh がコンテナイメージ golang:1.27.3-trixie 内で go-webauthn 0.18.2 を実行しました。このページの内容はその出力と一致していなければならず、各事実には該当する出力行を示しています。

  • デフォルトの COSE アルゴリズム

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

    BeginRegistration は COSE アルゴリズム -7、-35、-36(ES256/384/512)、-257、-258、-259(RS256/384/512)、-37、-38、-39(PS256/384/512)、-8(Ed25519)を列挙します。

    チェックによる記録
    fact webauthn-default-algorithms = -7, -35, -36, -257, -258, -259, -37, -38, -39, -8
  • デフォルトのアテステーション

    none

    アテステーションの伝達方法のデフォルトは none です。

    チェックによる記録
    fact webauthn-attestation = none
  • デフォルトのユーザー検証

    preferred

    authenticatorSelection はデフォルトで空のオブジェクトとして送信されるため、ブラウザーは preferred を適用します。

    チェックによる記録
    fact webauthn-user-verification = preferred
    evidence webauthn-user-verification: authenticatorSelection in BeginRegistration output: {}
  • デフォルトのレジデントキー

    discouraged

    オプションに residentKey がない場合は、WebAuthn のデフォルトである discouraged が適用されます。

    チェックによる記録
    fact webauthn-resident-key = discouraged
  • デフォルトでのユーザー検証の強制

    no

    セッションのユーザー検証が preferred のときは、UP だけが立った登録とアサーションが検証を通りました。required では、アサーションが User verification required but flag not set by authenticator で失敗しました。

    チェックによる記録
    fact webauthn-uv-enforced-by-default = no
    evidence webauthn-uv-enforced-by-default: registration with the UV flag clear, session UV preferred: verified
  • アサーション署名のエンコーディング

    der

    DER 署名を含む正しい ES256 アサーションは検証を通りました。

    チェックによる記録
    fact webauthn-assertion-encoding = der
  • 生の r‖s 形式のアサーション署名

    rejected

    64 バイトの生の r‖s 署名は Error validating the assertion signature: Signature invalid or not provided で失敗しました。

    チェックによる記録
    fact webauthn-raw-signature = rejected
  • high-S のアサーション署名

    accepted

    s を n − s に置き換えた DER 署名も検証を通りました。

    チェックによる記録
    fact webauthn-high-s = accepted
  • 署名カウンターの巻き戻り

    flagged

    保存済みの値が 5 のときにカウンター 3 を送ってもログインは失敗せず、返された認証情報は CloneWarning が true で、SignCount は 5 のままでした。

    チェックによる記録
    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
  • Ed25519 の認証情報

    supported

    Ed25519(COSE -8)の認証情報で、登録と認証に成功しました。

    チェックによる記録
    fact webauthn-ed25519 = supported
    evidence webauthn-ed25519: verified

使い方

ユーザー検証と検出可能な認証情報を必須とするようにリライングパーティを設定し、オプションとセッションに反映されたポリシーを確認します。
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)
}

スニペットのテストハーネスは、すべてのサンプルをコンテナイメージ golang:1.27.3-trixie 内でそのまま実行し、出力が一致しなければ実行は失敗します。

コマンド
GOFLAGS=-mod=mod go run .
一致すべき出力(正規表現)
uv: required required\nresident key: required

ライブラリ