JavaScript Object Signing and Encryption (JOSE) implemented in Go.
$ go get github.com/picatz/jose@latest
// Create a public/private key pair (ECDSA)
private, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
// Create a JWT token, sign it with the private key.
token, err := jwt.New(
header.Parameters{
header.Type: jwt.Type,
header.Algorithm: jwa.ES256,
},
jwt.ClaimsSet{
"sub": "1234567890",
"name": "John Doe",
},
private,
)
if err != nil {
panic(err)
}
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
bearerToken, err := jwt.FromHTTPAuthorizationHeader(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
token, err = jwt.ParseAndVerify(bearerToken, jwt.WithKey(&private.PublicKey))
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
sub, err := token.Claims.Get(jwt.Subject)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
if sub != "1234567890" {
w.WriteHeader(http.StatusUnauthorized)
return
}
name, err := token.Claims.Get("name")
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("Welcome back, %s!", name)))
})
fmt.Println("Listening on http://127.0.0.1:8080")
fmt.Printf("Try running: curl http://127.0.0.1:8080 -H 'Authorization: Bearer %s' -v\n", token)
err = http.ListenAndServe("127.0.0.1:8080", mux)
if err != nil {
panic(err)
}
- RFC7515 (JWS) JSON Web Signature
- RFC7516 (JWE) JSON Web Encryption
- RFC7517 (JWK) JSON Web Key
- RFC7518 (JWA) JSON Web Algorithms
- RFC7519 (JWT) JSON Web Token
JOSE was developed by an IETF working group, started in 2011. The group set out to develop a JSON syntax that could be used by applications to describe "secure data objects". It has become a well known, standardized mechanism for integrity protection and encryption, as well as the format for keys and algorithm identifiers to support interoperability of security services for protocols that use JSON.