Làm cách nào để xác minh thủ công chữ ký của JWT bằng khóa công khai của Google?

Jan 21 2021

Tôi đang triển khai đăng nhập Google bằng tập lệnh Go và tôi gặp khó khăn khi cố gắng xác minh Mã thông báo ID đã được ký bởi Google.

Cụ thể là tôi đang cố gắng thực hiện gạch đầu dòng đầu tiên ở đây .

Tôi đã lấy được mã thông báo và chia nó thành tiêu đề, trọng tải và chữ ký của nó. Nhưng tôi không biết cách sử dụng khóa công khai của Google để xác minh chữ ký.

Tôi thấy rằng việc tạo chữ ký liên quan đến thuật toán HMACSHA256 , nhưng tôi không biết phải làm gì với các khóa JWK hoặc PEM mà Google cung cấp. Tôi hiện đang làm thủ công do một số hạn chế nhất định.

Có ai biết làm thế nào tôi có thể xác minh chữ ký xin vui lòng?

Trả lời

2 yebowhatsay Jan 21 2021 at 17:20

Nhìn vào ví dụ php trên https://github.com/googleapis/google-api-php-client/blob/2fb6e702aca5d68203fa737f89f6f774022494c6/src/AccessToken/Verify.php#L90, có vẻ như API Google ký mã thông báo bằng RS256 (Chữ ký RSA với SHA-256).

Đoạn mã sau sẽ xác minh chữ ký và phân tích cú pháp mã thông báo. Không cần phải chia nhỏ mã thông báo trong mã của bạn. jwt.RSACheck (token [] byte, key * rsa.PublicKey) (* jwt.Claims, error) trong gói "github.com/pascaldekloe/jwt" sẽ thực hiện tất cả các công việc nặng nhọc cho bạn.

keyLocation là khóa công khai của Google được lưu trữ cục bộ

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
}