Keats / jsonwebtoken

JWT lib in rust
MIT License
1.61k stars 253 forks source link

Invalid signature #372

Open KevinNaidoo opened 4 months ago

KevinNaidoo commented 4 months ago

Hi,

I am having an issue when I use my generated token on other services (like pasting on the jwt.io website), it gives me an "Invalid signature". I have the following minimal example:-

#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Claims {
  iss: String,
  sub: String,
  iat: i64,
  exp: i64,
}

fn encode_decode_example() -> Result<(), Box<dyn std::error::Error>> {
    let encoding_key =
      EncodingKey::from_rsa_pem(include_bytes!("privateKey.pem"))?;
    let decoding_key =
      DecodingKey::from_rsa_pem(include_bytes!("publicKey.pem"))?;

    let iat = 1709145470;
    let exp = 1909546370;
    let claims = Claims {
      iss: "http://test_issuer.ai".to_string(),
      sub: "subject".to_string(),
      iat,
      exp,
    };

    let header = Header {
      alg: Algorithm::RS256,
      typ: Some("JWT".to_string()),
      ..Default::default()
    };
    let token = encode(&header, &claims, &encoding_key)?;

    println!("Token: {:?}", token);

    let token_data = decode::<Claims>(&token, &decoding_key, &Validation::new(Algorithm::RS256))?;
    println!("Token Data: {:?}", token_data.claims);

    Ok(())
  }

and I generate my keys like so:-

openssl genpkey -algorithm RSA -out privateKey.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in privateKey.pem -out publicKey.pem

The code works fine, no issues.

Any idea what the issue could be? I am generating my own access tokens to use with other services.

Thank you.

waynr commented 3 months ago

I've run into a similar issue and have identified the problem as being incompatible signature format.

In the product I am working on I am attempting to validate JWTs whose signatures were produced by google cloud's KMS. In KMS signature verification example doc we can see the doc writers assume a KMS-generated signature would be in ASN1 format:

        // Verify Elliptic Curve signature.
        var parsedSig struct{ R, S *big.Int }
        if _, err = asn1.Unmarshal(signature, &parsedSig); err != nil {
                return fmt.Errorf("asn1.Unmarshal: %w", err)
        }

But jsonwebtoken seems to assume a PKCS#11 style "fixed" signature serialization format

With no way to prefer (when signing) or detect (when verifying) the use of ASN1 for signature serialization.

I'd be willing to submit a PR to address this issue if the maintainer could provide guidance on the preferred approach for enabling the detection or selection of signature serialization format at the public crate api level. I imagine it could be as simple as providing encode_asn1 and decode_asn1 funtions.