¿Cómo verifico manualmente la firma de un JWT usando la clave pública de Google?

Jan 21 2021

Estoy implementando el inicio de sesión de Google en un script de Go y estoy atascado tratando de verificar que Google haya firmado el token de identificación.

Específicamente, estoy tratando de hacer el primer punto aquí .

Obtuve el token y lo dividí en su encabezado, carga útil y firma. Pero no sé cómo usar la clave pública de Google para verificar la firma.

Vi que la generación de firmas implica un algoritmo HMACSHA256 , pero no sé muy bien qué hacer con las claves JWK o PEM que proporciona Google. Actualmente lo estoy haciendo manualmente debido a ciertas restricciones.

¿Alguien sabe cómo puedo verificar la firma, por favor?

Respuestas

2 yebowhatsay Jan 21 2021 at 17:20

Mirando el ejemplo de php en https://github.com/googleapis/google-api-php-client/blob/2fb6e702aca5d68203fa737f89f6f774022494c6/src/AccessToken/Verify.php#L90, parece que la API de Google firma los tokens mediante RS256 (firma RSA con SHA-256).

El siguiente código debe verificar la firma y analizar el token. No es necesario dividir el token en su código. jwt.RSACheck (token [] byte, clave * rsa.PublicKey) (* jwt.Claims, error) en el paquete "github.com/pascaldekloe/jwt" haría todo el trabajo pesado por usted.

keyLocation es la clave pública de Google almacenada localmente

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
}