Come posso verificare manualmente la firma di un JWT utilizzando la chiave pubblica di Google?

Jan 21 2021

Sto implementando l'accesso Google in uno script Go e sono bloccato nel tentativo di verificare che il token ID sia stato firmato da Google.

In particolare, sto cercando di fare il primo punto elenco qui .

Ho ottenuto il token e l'ho suddiviso in intestazione, payload e firma. Ma non so come utilizzare la chiave pubblica di Google per verificare la firma.

Ho visto che la generazione della firma implica un algoritmo HMACSHA256 , ma non so cosa fare con le chiavi JWK o PEM fornite da Google. Attualmente lo sto facendo manualmente a causa di alcune restrizioni.

Qualcuno sa come posso verificare la firma per favore?

Risposte

2 yebowhatsay Jan 21 2021 at 17:20

Guardando l'esempio php su https://github.com/googleapis/google-api-php-client/blob/2fb6e702aca5d68203fa737f89f6f774022494c6/src/AccessToken/Verify.php#L90, sembra che l'API di Google firmi i token utilizzando RS256 (firma RSA con SHA-256).

Il codice seguente dovrebbe verificare la firma e analizzare il token. Non è necessario dividere il token nel codice. jwt.RSACheck (token [] byte, key * rsa.PublicKey) (* jwt.Claims, error) nel pacchetto "github.com/pascaldekloe/jwt" farebbe tutto il lavoro pesante per te.

keyLocation è la chiave pubblica di Google archiviata 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
}