Как разобрать набор JWK с помощью x5c и проверить JWT?

Я хочу проверить веб-токен JSON. Веб-ключ JSON для проверки доступен по этот URL-адрес. Это JWK с сертификатами x509 (x5c). Основываясь на ответе на другой вопрос, попробовал следующее:

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
}

Но я получаю следующую ошибку

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

Я не смог найти пример, использующий x5c. Решение не обязательно должно использовать библиотеку, которую я использовал в своем примере. Спасибо!


person katexochen    schedule 29.03.2021    source источник


Ответы (2)


Причина этой ошибки (required field e is missing) заключается в том, что набор JWK из этот URL-адрес недействителен. . Даже если JWK содержит x5c, он все равно должен содержать другие обязательные элементы открытого ключа. для этого конкретного kty, что для ключей RSA, перечисленных в этом URL-адресе, означает наличие n и e.

person Filip Skokan    schedule 29.03.2021
comment
Спасибо за Ваш ответ! Я думаю, что вы правы, это, кажется, проблема. Есть ли способ проверить токен в любом случае? Я имею в виду, что необходимая информация находится в части x5c. Я подумал о чем-то вроде преобразования содержимого x5c из DER в PEM и проверки с помощью пакета jwk с помощью PEM... - person katexochen; 30.03.2021
comment
У меня нет подробностей о вашем пакете, но когда x5c[0] получает декодированный base64url, это сертификат DER X.509. В сочетании с -----BEGIN CERTIFICATE-----\n + x5c[0] + \n-----END CERTIFICATE----- это действительный сертификат PEM X.509. - person Filip Skokan; 30.03.2021

Автор http://github.com/lestrrat-go/jwx здесь.

Я еще не объединил возможность анализировать сертификаты, ожидая ответа от репортера о проблеме, но код уже написан https://github.com/lestrrat-go/jwx/compare/topic/issue-350

Как только это изменение будет внесено, можно немного покрутить руками и проанализировать эти сертификаты (псевдокод):

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))

Если вам нужна возможность анализировать сертификаты в JWK, зарегистрируйте новую проблему в репозитории, чтобы я мог отслеживать изменения.

Кроме того, если вы импортируете http://github.com/lestrrat-go/jwx/jwk, вы также можете использовать http://github.com/lestrrat-go/jwx/jwt для JWT;)

person lestrrat    schedule 31.03.2021