Skip to content

Instantly share code, notes, and snippets.

@looselycoupled
Last active February 29, 2024 21:28
Show Gist options
  • Save looselycoupled/b2074b3f3e8b6800cddc6893ce8ef74a to your computer and use it in GitHub Desktop.
Save looselycoupled/b2074b3f3e8b6800cddc6893ce8ef74a to your computer and use it in GitHub Desktop.
Quick demonstration to create a JWKS, sign a token, and then validate it
package main
import (
"crypto/ed25519"
"crypto/rand"
"encoding/json"
"fmt"
"time"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/lestrrat-go/jwx/v2/jwt"
)
func make() (pubJWKSetBytes, tokenBytes []byte, err error) {
_, sk, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, nil, err
}
key, err := jwk.FromRaw(sk)
if err != nil {
return nil, nil, err
}
if err = key.Set(jwk.KeyIDKey, "ci-test-key"); err != nil {
return nil, nil, err
}
pkey, err := jwk.PublicKeyOf(key)
if err != nil {
return nil, nil, err
}
if err = pkey.Set(jwk.KeyIDKey, "ci-test-key"); err != nil {
return nil, nil, err
}
if err = pkey.Set(jwk.AlgorithmKey, jwa.EdDSA); err != nil {
return nil, nil, err
}
pubJWKSet := jwk.NewSet()
if err = pubJWKSet.AddKey(pkey); err != nil {
return nil, nil, err
}
pubJWKSetBytes, err = json.Marshal(pubJWKSet)
if err != nil {
return nil, nil, err
}
token, err := jwt.NewBuilder().
Issuer(`antimatter/ci`).
IssuedAt(time.Now()).
Subject(`test-user`).
Expiration(time.Now().Add(time.Hour * 24 * 3650)).
Build()
signedToken, err := jwt.Sign(token, jwt.WithKey(jwa.EdDSA, key))
if err != nil {
return nil, nil, err
}
// Verify the token
_, err = jwt.Parse(signedToken, jwt.WithKeySet(pubJWKSet), jwt.WithValidate(true))
if err != nil {
return nil, nil, err
}
return pubJWKSetBytes, signedToken, err
}
func validate(setBytes, tokenBytes []byte) error {
// Parse the JSON string to create a jwk.Set
set, err := jwk.Parse(setBytes)
if err != nil {
return fmt.Errorf("Error parsing JWKS: %w\n", err)
}
token, err := jwt.Parse(tokenBytes, jwt.WithKeySet(set), jwt.WithValidate(true))
if err != nil {
return fmt.Errorf("Failed to parse or verify JWT: %w\n", err)
}
fmt.Printf("Token: %#v\n", token)
return nil
}
func main() {
s, t, err := make()
if err != nil {
panic(err)
}
fmt.Printf("keyset: %s\n", s)
fmt.Printf("signed token: %s\n", t)
if err = validate(s, t); err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment