Safe, simple and fast JSON Web Tokens for Go

jwt

build-img pkg-img reportcard-img coverage-img

JSON Web Token for Go RFC 7519, also see jwt.io for more.

The latest version is v3.

Rationale

There are many JWT libraries, but many of them are hard to use (unclear or fixed API), not optimal (unneeded allocations + strange API). This library addresses all these issues. It's simple to read, to use, memory and CPU conservative.

Features

  • Simple API.
  • Clean and tested code.
  • Optimized for speed.
  • Dependency-free.
  • All well-known algorithms are supported
    • HMAC (HS)
    • RSA (RS)
    • RSA-PSS (PS)
    • ECDSA (ES)
    • EdDSA (EdDSA)
    • or your own!

Install

Go version 1.13+

GO111MODULE=on go get github.com/cristalhq/jwt/v3

Example

Build new token:

// create a Signer (HMAC in this example)
key := []byte(`secret`)
signer, err := jwt.NewSignerHS(jwt.HS256, key)
checkErr(err)

// create claims (you can create your own, see: Example_BuildUserClaims)
claims := &jwt.RegisteredClaims{
    Audience: []string{"admin"},
    ID:       "random-unique-string",
}

// create a Builder
builder := jwt.NewBuilder(signer)

// and build a Token
token, err := builder.Build(claims)
checkErr(err)

// here is token as byte slice
var _ []byte = token.Bytes() // or just token.String() for string

Parse and verify token:

// create a Verifier (HMAC in this example)
key := []byte(`secret`)
verifier, err := jwt.NewVerifierHS(jwt.HS256, key)
checkErr(err)

// parse a Token (by example received from a request)
tokenStr := `<header.payload.signature>`
token, err := jwt.ParseString(tokenStr)
checkErr(err)

// and verify it's signature
err = verifier.Verify(token.Payload(), token.Signature())
checkErr(err)

// also you can parse and verify together
newToken, err := jwt.ParseAndVerifyString(tokenStr, verifier)
checkErr(err)

// get standard claims
var newClaims jwt.StandardClaims
errClaims := json.Unmarshal(newToken.RawClaims(), &newClaims)
checkErr(errClaims)

// verify claims as you 
var _ bool = newClaims.IsForAudience("admin")
var _ bool = newClaims.IsValidAt(time.Now())

Also see examples: example_test.go.

Documentation

See these docs.

License

MIT License.

Comments
  • Slow Sign

    Slow Sign

    No benchmarks so I did a small comparison.

    goos: darwin
    goarch: amd64
    pkg: github.com/pascaldekloe/jwt
    BenchmarkCristalHQ/sign-HS256-4         	  543394	      2212 ns/op
    BenchmarkCristalHQ/check-HS256-4        	  271428	      4300 ns/op
    BenchmarkHMAC/sign-HS256-4              	  589506	      2034 ns/op	       123 B/token
    BenchmarkHMAC/check-HS256-4             	  274357	      4277 ns/op
    PASS
    ok  	github.com/pascaldekloe/jwt	5.242s
    
    func BenchmarkCristalHQ(b *testing.B) {
            // 512-bit key
            secret := make([]byte, 64)
    
            signer, err := cjwt.NewHS256(secret)
            if err != nil {
                    b.Fatal(err)
            }
            builder := cjwt.NewTokenBuilder(signer)
    
            claims := &cjwt.StandardClaims{
                    Issuer: benchClaims.Issuer,
                    IssuedAt: cjwt.Timestamp(*benchClaims.Issued),
            }
    
            var token []byte
            b.Run("sign-HS256", func(b *testing.B) {
                    for i := 0; i < b.N; i++ {
                            obj, err := builder.Build(claims)
                            if err != nil {
                                    b.Fatal(err)
                            }
                            token = obj.Raw()
                    }
            })
            b.Run("check-HS256", func(b *testing.B) {
                    for i := 0; i < b.N; i++ {
                            obj, err := cjwt.ParseAndVerify(token, signer)
                            if err != nil {
                                    b.Fatal(err)
                            }
                            err = json.Unmarshal(obj.RawClaims(), new(map[string]interface{}))
                            if err != nil {
                                    b.Fatal(err)
                            }
                    }
            })
    }
    
  • The jwt format is incorrect and panic directly

    The jwt format is incorrect and panic directly

    err = verifier.Verify(token.Payload(), token.Signature())

    Once the JWT format of the previous Token input is incorrect, this code will immediately panic Go1.17

    Error message: `panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x10 pc=0xbb6c0a]

    goroutine 1 [running]: github.com/cristalhq/jwt/v3.(*Token).Payload(...) C:/Users/SKER/go/pkg/mod/github.com/cristalhq/jwt/[email protected]/jwt.go:52 ncovGin/tools.VerifyToken({0xe2f985, 0xc000046000}) C:/go-src/ncovGin/tools/jwt.go:63 +0x6a main.main() C:/go-src/ncovGin/test/test.go:14 +0x25 `

  • Where should I give the secret on validation?

    Where should I give the secret on validation?

    In the validation example here https://github.com/cristalhq/jwt/blob/master/example_validate_test.go, it seems I didn't see any where to provide the secret/password on validation?

  • Add clear warnings for HS256 secret length

    Add clear warnings for HS256 secret length

    https://auth0.com/blog/brute-forcing-hs256-is-possible-the-importance-of-using-strong-keys-to-sign-jwts/

    The second key, secret is 48-bit. This is simply too short to be a valid key. In fact, the JSON Web Algorithms RFC 7518 states that a key of the same size as the hash output (for instance, 256 bits for "HS256") or larger MUST be used with the HS256 algorithm.

    I therefore recommend that anyone trying to generate a JSON Web token and signing them with HS256 to use a properly sized secret key. Auth0 secret keys are 512 bits in length and not susceptible to this type of brute force attack.

    I see too many examples using secret as a key without any warnings, please consider adding an example how to generate such key.

  • Update README to not use v3 prefix

    Update README to not use v3 prefix

    We tried to download jwt v3 by reference to README, however, We could not download the jwt v3, because it cannot find the package.

    ❯ go get github.com/cristalhq/jwt/v3
    cannot find package "github.com/cristalhq/jwt/v3" in any of:
    	/usr/local/go/src/github.com/cristalhq/jwt/v3 (from $GOROOT)
    	/Users/xxxxx/go/src/github.com/cristalhq/jwt/v3 (from $GOPATH)
    

    Therefore, we thought it necessary to update the README and changed the code to not use v3.

  • add sync.Pool to get hash.Hash where possible

    add sync.Pool to get hash.Hash where possible

    Similar to #44, just to make the same for all algorithms.

    benchcmp bench.old bench.new
    benchmark                        old ns/op     new ns/op     delta
    BenchmarkEDSA/Sign-EdDSA-4       66128         66932         +1.22%
    BenchmarkEDSA/Verify-EdDSA-4     170415        171653        +0.73%
    BenchmarkES/Sign-ES256-4         35060         36800         +4.96%
    BenchmarkES/Verify-ES256-4       95878         102948        +7.37%
    BenchmarkES/Sign-ES384-4         5640494       5328269       -5.54%
    BenchmarkES/Verify-ES384-4       14693353      11951887      -18.66%
    BenchmarkES/Sign-ES512-4         11918140      9458677       -20.64%
    BenchmarkES/Verify-ES512-4       27179389      20391382      -24.97%
    BenchmarkPS/Sign-PS256-4         2079814       1979967       -4.80%
    BenchmarkPS/Verify-PS256-4       110701        88832         -19.76%
    BenchmarkPS/Sign-PS384-4         2741718       1868684       -31.84%
    BenchmarkPS/Verify-PS384-4       161826        86363         -46.63%
    BenchmarkPS/Sign-PS512-4         2559179       1869384       -26.95%
    BenchmarkPS/Verify-PS512-4       95496         83714         -12.34%
    BenchmarkRS/Sign-RS256-4         1864396       1860276       -0.22%
    BenchmarkRS/Verify-RS256-4       84125         80451         -4.37%
    BenchmarkRS/Sign-RS384-4         1884087       1909896       +1.37%
    BenchmarkRS/Verify-RS384-4       80976         86621         +6.97%
    BenchmarkRS/Sign-RS512-4         1867908       1894707       +1.43%
    BenchmarkRS/Verify-RS512-4       80037         79639         -0.50%
    BenchmarkHS/Sign-HS256-4         3322          2914          -12.28%
    BenchmarkHS/Verify-HS256-4       1667          1299          -22.08%
    BenchmarkHS/Sign-HS384-4         3724          2998          -19.50%
    BenchmarkHS/Verify-HS384-4       1991          1410          -29.18%
    BenchmarkHS/Sign-HS512-4         3884          3086          -20.55%
    BenchmarkHS/Verify-HS512-4       2429          1435          -40.92%
    
    benchmark                        old allocs     new allocs     delta
    BenchmarkEDSA/Sign-EdDSA-4       18             18             +0.00%
    BenchmarkEDSA/Verify-EdDSA-4     2              2              +0.00%
    BenchmarkES/Sign-ES256-4         51             50             -1.96%
    BenchmarkES/Verify-ES256-4       21             20             -4.76%
    BenchmarkES/Sign-ES384-4         14474          14457          -0.12%
    BenchmarkES/Verify-ES384-4       29655          32629          +10.03%
    BenchmarkES/Sign-ES512-4         19591          19617          +0.13%
    BenchmarkES/Verify-ES512-4       50897          37498          -26.33%
    BenchmarkPS/Sign-PS256-4         129            128            -0.78%
    BenchmarkPS/Verify-PS256-4       19             18             -5.26%
    BenchmarkPS/Sign-PS384-4         129            128            -0.78%
    BenchmarkPS/Verify-PS384-4       19             18             -5.26%
    BenchmarkPS/Sign-PS512-4         129            128            -0.78%
    BenchmarkPS/Verify-PS512-4       19             18             -5.26%
    BenchmarkRS/Sign-RS256-4         123            122            -0.81%
    BenchmarkRS/Verify-RS256-4       13             12             -7.69%
    BenchmarkRS/Sign-RS384-4         123            122            -0.81%
    BenchmarkRS/Verify-RS384-4       13             12             -7.69%
    BenchmarkRS/Sign-RS512-4         123            122            -0.81%
    BenchmarkRS/Verify-RS512-4       13             12             -7.69%
    BenchmarkHS/Sign-HS256-4         18             13             -27.78%
    BenchmarkHS/Verify-HS256-4       6              1              -83.33%
    BenchmarkHS/Sign-HS384-4         18             13             -27.78%
    BenchmarkHS/Verify-HS384-4       6              1              -83.33%
    BenchmarkHS/Sign-HS512-4         18             13             -27.78%
    BenchmarkHS/Verify-HS512-4       6              1              -83.33%
    
    benchmark                        old bytes     new bytes     delta
    BenchmarkEDSA/Sign-EdDSA-4       1424          1424          +0.00%
    BenchmarkEDSA/Verify-EdDSA-4     293           295           +0.68%
    BenchmarkES/Sign-ES256-4         3954          3826          -3.24%
    BenchmarkES/Verify-ES256-4       1255          1131          -9.88%
    BenchmarkES/Sign-ES384-4         1752088       1750090       -0.11%
    BenchmarkES/Verify-ES384-4       3589214       3949067       +10.03%
    BenchmarkES/Sign-ES512-4         3027917       3032247       +0.14%
    BenchmarkES/Verify-ES512-4       7866515       5795388       -26.33%
    BenchmarkPS/Sign-PS256-4         32892         32771         -0.37%
    BenchmarkPS/Verify-PS256-4       5912          5762          -2.54%
    BenchmarkPS/Sign-PS384-4         33097         32890         -0.63%
    BenchmarkPS/Verify-PS384-4       6152          5909          -3.95%
    BenchmarkPS/Sign-PS512-4         33125         32901         -0.68%
    BenchmarkPS/Verify-PS512-4       6191          5949          -3.91%
    BenchmarkRS/Sign-RS256-4         32247         32121         -0.39%
    BenchmarkRS/Verify-RS256-4       5426          5297          -2.38%
    BenchmarkRS/Sign-RS384-4         32355         32132         -0.69%
    BenchmarkRS/Verify-RS384-4       5532          5311          -3.99%
    BenchmarkRS/Sign-RS512-4         32370         32158         -0.65%
    BenchmarkRS/Verify-RS512-4       5545          5329          -3.90%
    BenchmarkHS/Sign-HS256-4         1328          848           -36.14%
    BenchmarkHS/Verify-HS256-4       512           32            -93.75%
    BenchmarkHS/Sign-HS384-4         1696          896           -47.17%
    BenchmarkHS/Verify-HS384-4       848           48            -94.34%
    BenchmarkHS/Sign-HS512-4         1776          976           -45.05%
    BenchmarkHS/Verify-HS512-4       864           64            -92.59%
    
  • Key size check in getHashRS() in algo_rs.go is invalid

    Key size check in getHashRS() in algo_rs.go is invalid

    For "RS512", for example, it looks like it's checking that the provided private key's size is 512; the 512 there is the SHA hash size, and is unrelated to the RSA key being used.

    https://datatracker.ietf.org/doc/html/rfc7518#page-8

    It's bombing out incorrectly when I attempt to use a 2048 RSA key (with a keySize() of 256) with RS512, which should be fine.

  • Add func to generate random 512 bits key

    Add func to generate random 512 bits key

    Instead of showing people an insecure example, generate a key for them first

    // generate a key
    key, err := GenerateRandom512Bit()
    checkErr(err)
    
    // create a Signer (HMAC in this example)
    signer, err := jwt.NewSignerHS(jwt.HS256, key)
    checkErr(err)
    
    // create claims (you can create your own, see: Example_BuildUserClaims)
    claims := &jwt.RegisteredClaims{
        Audience: []string{"admin"},
        ID:       "random-unique-string",
    }
    
    // create a Builder
    builder := jwt.NewBuilder(signer)
    
    // and build a Token
    token, err := builder.Build(claims)
    checkErr(err)
    
    // here is token as a string
    var _ string = token.String()
    
  • Cannot find package

    Cannot find package "github.com/cristalhq/jwt/v3"

    Dear sir, could you please help me to understand how to install your package? I'm very new in Go, so maybe missing some simple thing here

    C:\Users\bob\go>go version
    go version go1.14.6 windows/amd64
    
    C:\Users\bob\go>go env GOROOT
    D:\software\Go
    
    C:\Users\bob\go>go env GOPATH
    C:\Users\bob\go
    
    C:\Users\bob\go>go get -v -u github.com/golang/example/hello
    github.com/golang/example (download)
    
    C:\Users\bob\go>%GOPATH%/bin/hello
    Hello, Go examples!
    
    C:\Users\bob\go>go get -v -u github.com/cristalhq/jwt/v3
    github.com/cristalhq/jwt (download)
    package github.com/cristalhq/jwt/v3: cannot find package "github.com/cristalhq/jwt/v3" in any of:
            D:\software\Go\src\github.com\cristalhq\jwt\v3 (from $GOROOT)
            C:\Users\bob\go\src\github.com\cristalhq\jwt\v3 (from $GOPATH)
    
  • Optimisation causing incorrect header to encode

    Optimisation causing incorrect header to encode

    encodeHeader in build.go checks if the header is a JWT, and then chooses a pre-encoded header as the result, as an optimization. However, a Header can also have a cty field or a kid field. AND, if either of these are set, the optimization will not encode them.

    I Suggest the if header.Type check also needs to ensure cty and kid are not set.

    This is the function in question.

    func encodeHeader(header *Header) []byte {
    	if header.Type == "JWT" {
    		switch header.Algorithm {
    		case NoEncryption:
    			return []byte("eyJhbGciOiJub25lIn0")
    		case EdDSA:
    			return []byte("eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9")
    
  • Error in readme -> Parse and verify token exemple

    Error in readme -> Parse and verify token exemple

    In Parse and verify token exemple line 12. is actually golang err = verifier.Verify(token) but is doesn't work because Verify Need two arguments. We can replace with golang err = verifier.Verify(token.Payload(), token.Signature())

  • Crypto Go :we are a research group to help developers build secure applications.

    Crypto Go :we are a research group to help developers build secure applications.

    Hi, we are a research group to help developers build secure applications. We designed a cryptographic misuse detector (i.e., CryptoGo) on Go language. We found your great public repository from Github, and several security issues detected by CryptoGo are shown in the following. Note that the cryptographic algorithms are categorized with two aspects: security strength and security vulnerability based on NIST Special Publication 800-57 and other public publications. Moreover, CryptoGo defined certain rules derived from the APIs of Go cryptographic library and other popular cryptographic misuse detectors. The specific security issues we found are as follows: Location: algo_rs.go:79; Broken rule: R-07: RSASSA-PKCS1-v1_5 is deprecated; We wish the above security issues could truly help you to build a secure application. If you have any concern or suggestion, please feel free to contact us, we are looking forward to your reply. Thanks.

  • JWK Set jwt.Verifier implementation

    JWK Set jwt.Verifier implementation

    I'm looking to create a separate helper Go package for this project. This helper Go package will verify JWTs are signed with a key in a JWK Set (JWKS). It helps users of this package by turning a JWKS into a jwt.Verifier to more conveniently verify keys.

    This would be similar to how github.com/MicahParks/keyfunc is a helper Go package for github.com/golang-jwt/jwt/v4.

    However, the jwt.Verifier interface has a method called Algorithm that must be implemented. From the Go docs, I can't infer how to implement this method, but looking at the source code, it seems to me that the jwt.Algorithm return parameter's value is the set of values I often see as the "alg" in JWT headers. Also glancing at the source code, it seems to me that the only use of the Algorithm method is in a _test.go file, so I'm not sure if an improper implementation of this method would affect anything.

    Before I continue developing this package, I wanted to confirm how to implement this Algorithm method, due to the fact that it's a part of the public facing API. Since a JWKS can contain multiple key types, it's not appropriate to return a single "alg" value. Perhaps one of the two options may be ideal?

    1. Add a new jwt.Algorithm value that indicates any algorithm can be verified.
    2. Remove the Algorithm method from the jwt.Verifier interface (would be a breaking change and require a major semver bump).
A simple and lightweight library for creating, formatting, manipulating, signing, and validating JSON Web Tokens in Go.

GoJWT - JSON Web Tokens in Go GoJWT is a simple and lightweight library for creating, formatting, manipulating, signing and validating Json Web Tokens

Nov 15, 2022
Microservice generates pair of access and refresh JSON web tokens signed by user identifier.

go-jwt-issuer Microservice generates pair access and refresh JSON web tokens signed by user identifier. ?? Deployed on Heroku Run tests: export SECRET

Nov 21, 2022
Golang implementation of JSON Web Tokens (JWT)

jwt-go A go (or 'golang' for search engine friendliness) implementation of JSON Web Tokens NEW VERSION COMING: There have been a lot of improvements s

Jan 6, 2023
A go implementation of JSON Web Tokens

jwt-go A go (or 'golang' for search engine friendliness) implementation of JSON Web Tokens NEW VERSION COMING: There have been a lot of improvements s

Jan 7, 2023
Oct 8, 2022
Generate and verify JWT tokens with Trusted Platform Module (TPM)

golang-jwt for Trusted Platform Module (TPM) This is just an extension for go-jwt i wrote over thanksgiving that allows creating and verifying JWT tok

Oct 7, 2022
Go module with token package to request Azure Resource Manager and Azure Graph tokens.

azAUTH Go module with token package to request Azure Resource Manager and Azure Graph tokens. prerequisites Install azure cli: https://docs.microsoft.

Dec 1, 2021
Generate and verify JWT tokens with PKCS-11

golang-jwt for PKCS11 Another extension for go-jwt that allows creating and verifying JWT tokens where the private key is embedded inside Hardware lik

Dec 5, 2022
OauthMicroservice-cassandraCluster - Implement microservice of oauth using golang and cassandra to store user tokens

implement microservice of oauth using golang and cassandra to store user tokens

Jan 24, 2022
Authenticated and encrypted API tokens using modern crypto

Branca Token Authenticated and encrypted API tokens using modern crypto. What? Branca is a secure, easy to use token format which makes it hard to sho

Dec 25, 2022
:key: Secure alternative to JWT. Authenticated Encrypted API Tokens for Go.

branca branca is a secure alternative to JWT, This implementation is written in pure Go (no cgo dependencies) and implements the branca token specific

Dec 29, 2022
Platform-Agnostic Security Tokens implementation in GO (Golang)

Golang implementation of PASETO: Platform-Agnostic Security Tokens This is a 100% compatible pure Go (Golang) implementation of PASETO tokens. PASETO

Jan 2, 2023
an stateless OpenID Connect authorization server that mints ID Tokens from Webauthn challenges

Webauthn-oidc Webauthn-oidc is a very minimal OIDC authorization server that only supports webauthn for authentication. This can be used to bootstrap

Nov 6, 2022
Minting OIDC tokens from GitHub Actions for use with OpenFaaS

minty Experiment for minting OIDC tokens from GitHub Actions for use with OpenFaaS Why would you want this? Enable third-parties to deploy to your ope

Oct 31, 2021
Golang jwt tokens without any external dependency

Yet another jwt lib This is a simple lib made for small footprint and easy usage It allows creating, signing, reading and verifying jwt tokens easily

Oct 11, 2021
Utility to generate tokens to interact with GitHub API via GitHub App integration

GitHub App Authentication for integration with GitHub Introduction GitHub Apps are the officially recommended way to integrate with GitHub because of

Mar 16, 2022
Generate a generic library of 2FA tokens compatible with Google Authenticator

towfa Generate a generic library of 2FA tokens compatible with Google Authenticator go get -u github.com/golandscape/twofa $twofa "you secret" result:

Mar 23, 2022
Authenticated encrypted API tokens (IETF XChaCha20-Poly1305 AEAD) for Golang

branca.go is branca token specification implementation for Golang 1.15+.

Dec 26, 2022
JSON Web Token library

About … a JSON Web Token (JWT) library for the Go programming language. Feature complete Full test coverage Dependency free Key management The API enf

Dec 19, 2022