Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validating Google Login Tokens #326

Open
Tapwatero opened this issue Sep 2, 2023 · 5 comments
Open

Validating Google Login Tokens #326

Tapwatero opened this issue Sep 2, 2023 · 5 comments

Comments

@Tapwatero
Copy link

I am quite sorry - as despite my best efforts and research I could not find any conclusive way of decoding google jwts.

Google uses RS256 to sign the tokens I receieve.


    match jsonwebtoken::decode::<Claims>(body.jwt.to_string().as_str(), &DecodingKey::from_secret(env::var("SECRET").unwrap().as_ref()), &Validation::new(Algorithm::RS256)) {
        Ok(res) => {
            println!("{:?}", res);
        },
        Err(error) => {
            println!("{error:}");
        }
    }

Doing this results in InvalidAlgorithm.
Anyone know how to fix this.

@Keats
Copy link
Owner

Keats commented Sep 4, 2023

There is not enough information to resolve the issue. Can you provide an example key and JWT?

@nlopes
Copy link

nlopes commented Nov 22, 2023

I might be able to help. Instead of doing Validation::new(Algorithm::RS256) do Validation::new(header.alg) where header is:

let header = jwt::decode_header(jwt);

In total it should be something like:

# Let's assume your jwt content is in a `&str` named `jwt` and
# const GOOGLE_APIS_TOKEN_URL: &str = "https://www.googleapis.com/robot/v1/metadata/x509/[email protected]";

let header = jwt::decode_header(jwt);

match header.kid {
  None => { oops },
  Some(kid) => {
       let secret = tokens /* this comes from the content at the url GOOGLE_APIS_TOKEN_URL (I've put it into a HashMap mapping kid to the secret */
                .get(kid.as_str())?;
        let jwt_payload = jwt::decode::<Claims>(
                jwt,
                &jwt::DecodingKey::from_rsa_pem(secret.as_bytes())?,
                &jwt::Validation::new(header.alg),
            )?;
  }
}

The above is some copy&paste from a project and some "old" knowledge so forgive me if I got something wrong.

@Ali-Javanmardi
Copy link

I might be able to help. Instead of doing Validation::new(Algorithm::RS256) do Validation::new(header.alg) where header is:

let header = jwt::decode_header(jwt);

In total it should be something like:

# Let's assume your jwt content is in a `&str` named `jwt` and
# const GOOGLE_APIS_TOKEN_URL: &str = "https://www.googleapis.com/robot/v1/metadata/x509/[email protected]";

let header = jwt::decode_header(jwt);

match header.kid {
  None => { oops },
  Some(kid) => {
       let secret = tokens /* this comes from the content at the url GOOGLE_APIS_TOKEN_URL (I've put it into a HashMap mapping kid to the secret */
                .get(kid.as_str())?;
        let jwt_payload = jwt::decode::<Claims>(
                jwt,
                &jwt::DecodingKey::from_rsa_pem(secret.as_bytes())?,
                &jwt::Validation::new(header.alg),
            )?;
  }
}

The above is some copy&paste from a project and some "old" knowledge so forgive me if I got something wrong.

@nlopes , I think there is a security risk in your suggested code.
there is a known trick that someone can make a crafted token and sign it by a well known RS256 public key but with HS256 algorithm,
So when your code trust on the algorithm introduced by token header it will validate token by HS256 instead of RS256 and falsely validate it as true.

@Codename-404
Copy link

Codename-404 commented Apr 18, 2024

Same issue, i can't verify jwt from google oauth.

            `let token = decode::<Claims>(
                &google_res.id_token,
                &DecodingKey::from_secret(google_client_secret.as_ref()),
                &Validation::new(Algorithm::RS256),
            );`
            
            this always returns InvalidAlgorithm

@Codename-404
Copy link

     ` let key = DecodingKey::from_secret(&[]);
            let mut validation = Validation::new(Algorithm::HS256);
            validation.insecure_disable_signature_validation();
            validation.validate_exp = false;
            validation.validate_aud = false;

            let payload = decode::<GoogleTokenInfo>(&google_res.id_token, &key, &validation);`

This is how you can decode google token, as it's coming from google and verified there, we don't need to verify again anyway. However make sure to verify your own token with your secret before using any claims.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants