简体   繁体   中英

How to parse a set of JWK with x5c and verify JWT?

I want to validate a JSON Web Token. The JSON Web Key for the verification are avaiable under this url . Those are JWKs with x509 certificates (x5c). Based on an answer to another question , tried the following:

import  "github.com/dgrijalva/jwt-go"
import  "github.com/lestrrat-go/jwx/jwk"

func verifyToken(tokenBytes []byte) {
    token, err := jwt.Parse(string(tokenBytes), getKey)
    if err != nil {
        panic(err)
    }
}

func getKey(token *jwt.Token) (interface{}, error) {
    set, err := jwk.Fetch(context.Background(), "https://shareduks.uks.attest.azure.net/certs")
    if err != nil {
        return nil, err
    }
    keyID, ok := token.Header["kid"].(string)
    if !ok {
        return nil, err
    }
    key, ok := set.LookupKeyID(keyID)
    if !ok {
        return nil, errors.New("could not find key with kid")
    }
    return key, nil
}

But I get the following error

panic: failed to parse JWK set: failed to unmarshal JWK set: failed to unmarshal key #1 (total 5) from multi-key JWK set: failed to unmarshal JSON into key (*jwk.rsaPublicKey): required field e is missing

I could not find an example that uses x5c. A solution does not have to use the library I used in my example. Thanks!

The reason for that error ( required field e is missing ) is that the JWK Set from this url is invalid. Even if a JWK contains x5c it still must contain the other required public key members for that specific kty , which for the RSA keys listed in that URL means having n and e .

Author of http://github.com/lestrrat-go/jwx here.

I have not merged the ability to parse certificates yet pending response from the issue reporter, but the code is already written https://github.com/lestrrat-go/jwx/compare/topic/issue-350

Once that change is in, it is possible to perform some arm twisting and parse those certificates (pseudocode):

data := ... read from that URL ...

rawSet := make(map[string]interface{})
if err := json.Unmarshal(data, &rawSet); err != nil {
   ...
}

// yikes
keys := rawset["keys"].([]interface{})
firstKey := keys[0].(map[string]interface{})
x5c := (firstKey["x5c"].([]interface{}))[0].(string)

// Decode from base64 
cert, _ := base64.RawStdEncoding.DecodeString(x5c)

// turn the certificate into JWK (NOT YET MERGED)
key, _ := jwk.ParseKey(cert, jwk.WithPEM(true))

If you need the ability to parse certificates into JWKs, please file a new issue in the repository so I can track the change.

Also, if you are importing http://github.com/lestrrat-go/jwx/jwk , you might as well use http://github.com/lestrrat-go/jwx/jwt for JWTs;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM