golang-jwt / jwt

Go implementation of JSON Web Tokens (JWT).

Home Page:https://golang-jwt.github.io/jwt/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ECDSA signature is invalid

bentcoder opened this issue · comments

Hi,

I am creating a ECDSA 256 to use with SigningMethodES256 to generate signed token. However the signature is said to be invalid when checking with https://jwt.io/. Could someone tell me if there is a bug or am I missing something please?

Thank you

Playground

package main

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

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

func main() {
	ecdsa, err := NewECDSA(elliptic.P256())
	if err != nil {
		panic(err)
	}

	jwt := JWT{
		Issuer:        "my-api",
		SigningMethod: jwt.SigningMethodES256,
		PublicKey:     ecdsa.Public,
		PrivateKey:    ecdsa.Private,
	}

	token, err := jwt.CreateToken(context.Background(), CreateTokenArgs{
		ID:       "token-id-1",
		ClientID: "client-id-1",
		Now:      time.Now().UTC(),
		TTL:      time.Hour,
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(token)
}

// ECDSA ------------------------------------------------------

type ECDSA struct {
	Private *ecdsa.PrivateKey
	Public  *ecdsa.PublicKey
}

func NewECDSA(curve elliptic.Curve) (ECDSA, error) {
	prv, err := ecdsa.GenerateKey(curve, rand.Reader)
	if err != nil {
		return ECDSA{}, err
	}

	return ECDSA{
		Private: prv,
		Public:  &prv.PublicKey,
	}, nil
}

// JWT --------------------------------------------------------

type CreateTokenArgs struct {
	ID       string
	ClientID string
	Now      time.Time
	TTL      time.Duration
}

type JWT struct {
	Issuer        string
	SigningMethod jwt.SigningMethod
	PublicKey     any
	PrivateKey    any
}

func (j *JWT) CreateToken(ctx context.Context, args CreateTokenArgs) (string, error) {
	token := jwt.NewWithClaims(j.SigningMethod, jwt.RegisteredClaims{
		ID:        args.ID,
		Subject:   args.ClientID,
		Issuer:    j.Issuer,
		ExpiresAt: jwt.NewNumericDate(args.Now.Add(args.TTL)),
		NotBefore: jwt.NewNumericDate(args.Now),
		IssuedAt:  jwt.NewNumericDate(args.Now),
	})

	sig, err := token.SignedString(j.PrivateKey)
	if err != nil {
		return "", err
	}

	return sig, nil
}