Skip to content
ecdsa.com
go-jose (Go)Go

Error message

go-jose/go-jose: error in cryptographic primitive

Also printed as

  • square/go-jose: error in cryptographic primitive

go-jose v2 (imported as gopkg.in/square/go-jose.v2) used the prefix "square/go-jose:"; v3 and v4 use "go-jose/go-jose:". The same error is returned for JWE decryption failures.

go-jose (Go) — jose.ErrCryptoFailure from JSONWebSignature.Verify / jwt.JSONWebToken.Claims

What it means

go-jose's generic signature (or decryption) failure, `jose.ErrCryptoFailure`. The JWS parsed and the algorithm was allowed, but verifying the signature with the key you passed failed. go-jose deliberately does not say more — wrong key and modified token look the same to a verifier — so the investigation is always: which key did you pass, and was the token changed?

Why it happens

How to fix it

  1. 1.

    Select the key by kid, then validate claims

    Resolve exactly one key by the header's `kid` from the issuer's JWKS, verify, and then validate `iss`, `aud` and `exp` with `Claims.Validate` — go-jose does not check claims on its own.

    go
    // keys: *jose.JSONWebKeySet fetched from the issuer's jwks_uri
    parsed, err := jwt.ParseSigned(raw, []jose.SignatureAlgorithm{jose.ES256})
    if err != nil {
    	return err
    }
    kid := parsed.Headers[0].KeyID
    matches := keys.Key(kid) // all keys with this kid
    if len(matches) != 1 {
    	return fmt.Errorf("no unique key for kid %q", kid)
    }
    var claims jwt.Claims
    if err := parsed.Claims(matches[0].Key, &claims); err != nil {
    	return err
    }
    return claims.Validate(jwt.Expected{Issuer: "https://issuer.example.com/", AnyAudience: jwt.Audience{"api"}, Time: time.Now()})

Related errors

Browse the full signature error database