Googleの公開鍵を使用してJWTの署名を手動で確認するにはどうすればよいですか?

Jan 21 2021

GoスクリプトでGoogleログインを実装していますが、IDトークンがGoogleによって署名されていることを確認しようとして立ち往生しています。

具体的には、ここで最初の箇条書きを実行しようとしています。

トークンを取得し、ヘッダー、ペイロード、署名に分割しました。しかし、Googleの公開鍵を使用して署名を検証する方法がわかりません。

署名の生成にはHMACSHA256アルゴリズムが含まれていることを確認しましたが、Googleが提供するJWKまたはPEMキーをどう処理するかはよくわかりません。私は現在、特定の制限のために手動でそれを行っています。

署名を確認する方法を知っている人はいますか?

回答

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(SHA-256を使用したRSA署名)を使用してトークンに署名しているようです。

次のコードは、署名を検証し、トークンを解析する必要があります。コード内でトークンを分割する必要はありません。「github.com/pascaldekloe/jwt」パッケージのjwt.RSACheck(token [] byte、key * rsa.PublicKey)(* jwt.Claims、error)は、すべての面倒な作業を行います。

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
}