Bagaimana cara memverifikasi tanda tangan JWT secara manual menggunakan kunci publik Google?

Jan 21 2021

Saya mengimplementasikan login Google dalam skrip Go dan saya terjebak mencoba memverifikasi Token ID telah ditandatangani oleh Google.

Secara khusus saya mencoba melakukan poin pertama di sini .

Saya telah memperoleh token dan membaginya menjadi header, payload, dan tanda tangannya. Tapi saya tidak tahu bagaimana menggunakan kunci publik Google untuk memverifikasi tanda tangannya.

Saya melihat bahwa membuat tanda tangan melibatkan algoritme HMACSHA256 , tetapi saya tidak begitu tahu apa yang harus dilakukan dengan kunci JWK atau PEM yang disediakan Google. Saat ini saya melakukannya secara manual karena batasan tertentu.

Adakah yang tahu bagaimana saya bisa memverifikasi tanda tangan?

Jawaban

2 yebowhatsay Jan 21 2021 at 17:20

Lihat contoh php di https://github.com/googleapis/google-api-php-client/blob/2fb6e702aca5d68203fa737f89f6f774022494c6/src/AccessToken/Verify.php#L90, tampaknya Google API menandatangani token menggunakan RS256 (Tanda Tangan RSA dengan SHA-256).

Kode berikut harus memverifikasi tanda tangan dan mengurai token. Tidak perlu membagi token dalam kode Anda. jwt.RSACheck (token [] byte, key * rsa.PublicKey) (* jwt.Claims, error) dalam paket "github.com/pascaldekloe/jwt" akan melakukan semua pekerjaan berat untuk Anda.

keyLocation adalah kunci publik Google yang disimpan secara lokal

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
}