使用 jwt-cpp 验证 google IdToken

verify google IdToken with jwt-cpp

如何使用 jwt-cpp 库或 C++ 上的其他库验证 google tokenId jwt?我试图在 github 上重做库中的示例,但我没有足够的令牌知识来正确地做所有事情,这就是我得到的:

  std::string raw_jwks =
            R"({
  "keys": [
    {
      "kid": "486f16482005a2cdaf26d9214018d029ca46fb56",
      "e": "AQAB",
      "n": "pKFKLmDnNozPu24-nCrbvbBjO0gith7VmxPm1px9lkJfwXOWEbNzyfDhd3SjylKTyH5lq6zMtJvNvKCr2TyQTwypvmZBpeMK29Zz0WvgPBFJ6HHsu9apa21hgE9iPf0A1lNG5Nd2kP9m2Kc8ekKy4OrshDp6gs1ntHPWiW2iSjttruFjTB20P7p5GTdlxzg6LCrJ03E7FJlrfXcEEKRDzZ4h3b6hN2aZ_heOZxRSZ6Uwx8_tbFRe2TIfw9IXaXXuodHMRottSIZBtdJdOanbIFAuhEev9b-lFTksFQXDvicUiz_ri4JDliGuEAgINHjI6pcNo2vkYx3NupROmkDRIQ",
      "use": "sig",
      "alg": "RS256",
      "kty": "RSA"
    },
    {
      "kty": "RSA",
      "alg": "RS256",
      "n": "h0G4nnQc39gn04fTuSJB6l1JhE9ggG-SHrc9yfr85tzQEjxG55jipmnmW1x-IHS1PvWgtNbpeEDya9IUzkC8BxnBht7WVDV9mLBZK8szrCrj6l7SwvQOM6cw0-KgGgmzwE_IGkn452wmlVYz9IIY-etasrkstJ0G2smQJ3Db3YbZe32FoYnXbbK38O2hIf4bffegccrfmsEEbSisq0903IEbCi0qpJbhrgqvYg6_y0KeOxxX5u-_Jg-KM0Aub4YGT2LRsiE_ygskabuoh6nQDr8M9-SDC_bEind2FUk761ZSw_QMk9_Nc9orllaMZpQ4FpKRv5LXHUawz_er8P3c0w",
      "use": "sig",
      "kid": "38f3883468fc659abb4475f36313d22585c2d7ca",
      "e": "AQAB"
    }
  ]
}
)";

        std::string token =
            "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
            "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."
            "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";

        auto decoded_jwt = jwt::decode(token);
        auto jwks = jwt::parse_jwks(raw_jwks);
        auto jwk = jwks.get_jwk(decoded_jwt.get_key_id());

        auto issuer = decoded_jwt.get_issuer();
        auto x5c = jwk.get_x5c_key_value();

        if (!x5c.empty() && !issuer.empty()) {
            auto verifier =
                jwt::verify()
                    .allow_algorithm(jwt::algorithm::rs256(jwt::helper::convert_base64_der_to_pem(x5c), "", "", ""))
                    .with_issuer(issuer)
                    .leeway(60UL); // value in seconds, add some to compensate timeout

            verifier.verify(decoded_jwt);
        } 

但是我在JWK中没有x5c,只有“e”和“n”,我该怎么办?

您问题中的数组 raw_jwks 是一个 JSON Web 密钥集 (JWKS)。这包含一个 public 键数组。密钥 ID 是您拥有的 kid 或通常的 x5c.

一些库接受原始数字格式(n 和 e)的 public 密钥,其他库则要求您首先从这些数字创建 PKCS 格式的 public 密钥。我没有使用你的库,所以请查阅文档以了解所需的格式和转换函数。

由于您不知道用于签署 JWT 的实际私钥 ID,因此您必须循环遍历 raw_jwks 检查每个签名验证是否成功。如果都不成功,则报告失败。

供以后参考,在Google云中有两种类型的private/public键。由 Google Cloud 管理的那些(只有 public 密钥可用)和服务帐户密钥。

Google Cloud 的 public 密钥位于此处:

https://www.googleapis.com/oauth2/v1/certs

对于服务帐户,他们以此 URL 开头并附加服务帐户电子邮件地址:

https://www.googleapis.com/robot/v1/metadata/x509/