ฉันจะตรวจสอบลายเซ็นของ JWT ด้วยตนเองโดยใช้คีย์สาธารณะของ Google ได้อย่างไร

Jan 21 2021

ฉันใช้การเข้าสู่ระบบ Google ในสคริปต์ Go และฉันติดขัดในการพยายามตรวจสอบว่า ID Token ได้รับการลงนามโดย 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 Signature with 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
}