Aller au contenu
ecdsa.com
Go

golang-jwt/jwt

golang-jwt/jwt, successeur de dgrijalva/jwt-go maintenu par la communauté et paquet JWT le plus utilisé en Go : vérification typée par la clé, none derrière une sentinelle explicite et expiration facultative, sauf si vous l’exigez.
Licence
MIT
Version vérifiée
5.3.1 ·
Code source
github.com/golang-jwt/jwt
Documentation
pkg.go.dev/github.com/golang-jwt/jwt/v5

Compatibilité en un coup d’œil

JOSE et JWT

Algorithmes JWS
HS256HS384HS512RS256RS384RS512PS256PS384PS512ES256ES384ES512EdDSA

github.com/golang-jwt/jwt/v5 analyse, valide et signe des JWT avec les clés de la bibliothèque standard : []byte pour HMAC, *rsa.PublicKey, *ecdsa.PublicKey et ed25519.PublicKey. La 5.3.1 a signé et vérifié les familles HS, RS, PS et ES ainsi qu’EdDSA ; ES256K et les noms entièrement spécifiés Ed25519 et Ed448 n’ont aucune méthode de signature enregistrée.

La vérification repose sur la keyfunc que vous passez à jwt.Parse. Chaque méthode de signature contrôle le type Go de la clé qu’elle reçoit : avec une keyfunc qui renvoie *ecdsa.PublicKey, un jeton RS256 a échoué avec RSA verify expects *rsa.PublicKey et un jeton HS256 dont la clé HMAC était le texte PEM a échoué avec HMAC verify expects []byte. Cette protection disparaît si la keyfunc renvoie des octets bruts pour chaque jeton : lors des essais, une keyfunc qui charge le fichier PEM en []byte a permis à ce jeton HS256 falsifié de passer la vérification. Passez jwt.WithValidMethods avec l’algorithme exact et gardez une keyfunc typée, comme le fait l’exemple.

alg: none ne passe la vérification que lorsque la keyfunc renvoie la sentinelle jwt.UnsafeAllowNoneSignatureType ; toute vraie clé donne 'none' signature type is not allowed. ES256 refuse une clé P-384 à la signature avec un laconique key is invalid. Les signatures ES256 sont au format r‖s brut de 64 octets qu’exige JWS ; une signature DER échoue avec crypto/ecdsa: verification error, une erreur que le débogueur JWT et le convertisseur DER ⇄ brut aident à diagnostiquer.

La validation des claims est active par défaut dans la v5, mais exp est facultatif (un jeton qui n’en a pas reste valide indéfiniment) et il n’y a aucune marge de tolérance. jwt.WithExpirationRequired(), jwt.WithIssuer, jwt.WithAudience et jwt.WithLeeway comblent ces lacunes ; les erreurs peuvent être identifiées avec errors.Is(err, jwt.ErrTokenExpired) plutôt qu’en comparant des chaînes.

Pour vérifier les jetons d’un fournisseur d’identité, associez golang-jwt à un client JWKS et contrôlez ce que publie le fournisseur avec le vérificateur JWKS ; go-jose est l’alternative lorsqu’il faut gérer JWE ou JWK.

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/golang-jwt/run.sh a exécuté golang-jwt/jwt 5.3.1 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 JWS

    HS256HS384HS512RS256RS384RS512PS256PS384PS512ES256ES384ES512EdDSA

    Signature et vérification réussies avec HS, RS, PS et ES en 256/384/512 bits et EdDSA ; ES256K, Ed25519 et Ed448 n’ont aucune méthode de signature enregistrée.

    Relevé par la vérification
    fact jws-algorithms = HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, EdDSA
    evidence jws-algorithms: ES256K: no signing method registered
    evidence jws-algorithms: Ed25519: no signing method registered
    evidence jws-algorithms: Ed448: no signing method registered
  • Encodage des signatures ES256

    raw

    Les signatures ES256 font 64 octets, en r‖s brut.

    Relevé par la vérification
    fact jws-ecdsa-encoding = raw
  • Signature DER dans un JWS

    rejected

    Une signature ES256 encodée en DER échoue avec token signature is invalid: crypto/ecdsa: verification error.

    Relevé par la vérification
    fact jws-der-signature = rejected
    evidence jws-der-signature: token signature is invalid: crypto/ecdsa: verification error
  • Liste d’algorithmes autorisés

    from-key

    Sans WithValidMethods, c’est le type Go de la clé qui décide : un jeton RS256 présenté à une keyfunc renvoyant une clé EC a échoué avec key is of invalid type: RSA verify expects *rsa.PublicKey.

    Relevé par la vérification
    fact jwt-algorithm-allowlist = from-key
    evidence jwt-algorithm-allowlist: RS256 token, keyfunc returning the EC public key, no WithValidMethods: token signature is invalid: key is of invalid type: RSA verify expects *rsa.PublicKey
  • Jetons non signés (alg none)

    opt-in

    Un jeton non signé échoue avec 'none' signature type is not allowed, sauf si la keyfunc renvoie jwt.UnsafeAllowNoneSignatureType.

    Relevé par la vérification
    fact jwt-alg-none = opt-in
    evidence jwt-alg-none: with the EC key: token signature is invalid: token is unverifiable: 'none' signature type is not allowed
    evidence jwt-alg-none: keyfunc returning jwt.UnsafeAllowNoneSignatureType: <nil>
  • Clé publique utilisée comme secret HMAC

    rejected

    Un jeton HS256 dont la clé HMAC était le texte PEM a échoué face à une keyfunc renvoyant *ecdsa.PublicKey (HMAC verify expects []byte), mais a été vérifié quand la keyfunc renvoyait les octets PEM.

    Relevé par la vérification
    fact jwt-hmac-public-key = rejected
    evidence jwt-hmac-public-key: keyfunc returning *ecdsa.PublicKey: token signature is invalid: key is of invalid type: HMAC verify expects []byte
    evidence jwt-hmac-public-key: keyfunc returning the PEM bytes (a keyfunc that loads keys as bytes): <nil>
  • Courbe vérifiée par rapport à alg

    enforced

    La signature ES256 avec une clé P-384 échoue avec key is invalid.

    Relevé par la vérification
    fact jwt-ecdsa-curve-check = enforced
    evidence jwt-ecdsa-curve-check: key is invalid
  • Décalage d’horloge toléré par défaut

    0s

    Aucune marge de tolérance par défaut : un jeton expiré depuis trois secondes a été rejeté.

    Relevé par la vérification
    fact jwt-clock-skew = 0s
  • Claim d’expiration obligatoire

    no

    Un jeton sans exp était valide ; avec WithExpirationRequired(), il échoue avec token is missing required claim: exp claim is required.

    Relevé par la vérification
    fact jwt-exp-required = no
    evidence jwt-exp-required: with WithExpirationRequired: token has invalid claims: token is missing required claim: exp claim is required

Utilisation

Signer des claims enregistrés en ES256 et les relire avec une keyfunc typée, la méthode fixée, et l’émetteur, l’expiration et la marge de tolérance imposés.
package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"
	"time"

	"github.com/golang-jwt/jwt/v5"
)

func main() {
	key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	claims := jwt.RegisteredClaims{Subject: "user-42", Issuer: "https://auth.example.com", ExpiresAt: jwt.NewNumericDate(time.Now().Add(10 * time.Minute))}
	signed, _ := jwt.NewWithClaims(jwt.SigningMethodES256, claims).SignedString(key)

	// The keyfunc returns a typed key; the options pin the method and the claims.
	token, err := jwt.ParseWithClaims(signed, &jwt.RegisteredClaims{},
		func(*jwt.Token) (any, error) { return &key.PublicKey, nil },
		jwt.WithValidMethods([]string{"ES256"}),
		jwt.WithIssuer("https://auth.example.com"),
		jwt.WithExpirationRequired(),
		jwt.WithLeeway(30*time.Second),
	)
	fmt.Println("valid:", err == nil && token.Valid, "sub:", token.Claims.(*jwt.RegisteredClaims).Subject)
}

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
valid: true sub: user-42

Bibliothèques