Как вручную проверить подпись JWT с помощью открытого ключа Google?

Jan 21 2021

Я реализую вход в систему Google в сценарии Go, и я застрял, пытаясь проверить, был ли токен идентификатора подписан Google.

В частности, я пытаюсь указать здесь на первом пункте .

Я получил токен и разделил его на заголовок, полезную нагрузку и подпись. Но я не знаю, как использовать открытый ключ Google для проверки подписи.

Я видел, что для генерации подписи используется алгоритм HMACSHA256 , но я не совсем знаю, что делать с ключами JWK или PEM, которые предоставляет Google. Сейчас делаю вручную из-за определенных ограничений.

Кто-нибудь знает, пожалуйста, как проверить подпись?

Ответы

2 yebowhatsay Jan 21 2021 at 17:20

Глядя на пример php на https://github.com/googleapis/google-api-php-client/blob/2fb6e702aca5d68203fa737f89f6f774022494c6/src/AccessToken/Verify.php#L90, похоже, что Google API подписывает токены с помощью RS256 (подпись RSA с SHA-256).

Следующий код должен проверить подпись и проанализировать токен. Нет необходимости разделять токен в вашем коде. jwt.RSACheck (token [] byte, key * rsa.PublicKey) (* jwt.Claims, error) в пакете github.com/pascaldekloe/jwt сделает всю тяжелую работу за вас.

keyLocation - это открытый ключ Google, хранящийся локально.

package main

import "github.com/pascaldekloe/jwt"

//jwtValidator verifies and parses the JWT Token
func jwtValidator(token string, keyLocation string) (j *jwtToken, err error) {
    token := []byte(token)

    pubK, err := rsaPublicKey(keyLocation)
    if err != nil {
        return
    }

    // parses the token only if signature is valid
    claims, err := jwt.RSACheck(token, pubK)
    if err != nil {
        err = fmt.Errorf("token signature invalid %s", err)
        return
    }
    if !claims.Valid(time.Now()) {
        err = fmt.Errorf("token time constraints exceeded")
        return
    }

    j = &jwtToken{
        id:      claims.ID,
        issuer:  claims.Issuer,
        issued:  claims.Issued,
        subject: claims.Subject,
        expires: claims.Expires,
    }

    return
}