jwt-dotnet / jwt

Jwt.Net, a JWT (JSON Web Token) implementation for .NET
Other
2.13k stars 462 forks source link

Decode does not break on wrong signature #473

Closed hanselsen closed 1 year ago

hanselsen commented 1 year ago

Using the code below:
When I parse the token with jwt.io, I can conclude that the token is created properly. However, the decoding ALWAYS succeeds. With the code below the decoded is always set. No exceptions are thrown.

Do I not understand the library, or is this a bug?

var data = new
{
    test = 1234
};
var contents = System.IO.File.ReadAllText("jwt.pem");
var parts = contents.Split("-\n-");
var certificate = X509Certificate2.CreateFromPem("-" + parts[1], parts[0] + "-");
var key = certificate.Export(X509ContentType.Pkcs12);

var algorithm = new RS512Algorithm(certificate);
var urlEncoder = new JwtBase64UrlEncoder();
var serializer = new JsonNetSerializer(Newtonsoft.Json.JsonSerializer.CreateDefault());
var provider = new UtcDateTimeProvider();
var validator = new JwtValidator(serializer, provider);
var jwtEncoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var jwtDecoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);

var token = jwtEncoder.Encode(data, key);
var decoded = jwtDecoder.Decode(token, new byte[0]); //<-- this should break the decoding right?
return new
{
    token, decoded
};
abatishchev commented 1 year ago

Hi, In general, to better assist you, please provide the version of the library and the target framework.

But in this particular case, this information is not needed. The second parameter key/keys is an artifact of the past and is used only by symmetric algorithms. Here's the code:

https://github.com/jwt-dotnet/jwt/blob/9b9484f6b26e575cdc2377bc038d161aa5c7f501/src/JWT/JwtDecoder.cs#L248-L255

In case of asymmetric algorithm, the instance of an algorithm holds the certificate object and uses it to validate the signature:

https://github.com/jwt-dotnet/jwt/blob/9b9484f6b26e575cdc2377bc038d161aa5c7f501/src/JWT/JwtValidator.cs#L142-L143

Hope this helps.

hanselsen commented 1 year ago

@abatishchev thanks so much. As I understand correctly, passing the key/keys to the decoding has no effect at all, because it uses the certificate in my algorithm. I can safely assume that the data is verified during the decoding process? 🙂

I guess where I got confused was that JwtEncoder.Encode expects either a string or a byte[], whereas JwtDecoder.Decode is fine with just the token. Anyhow, I now have the following:

JwtEncoder.Encode(payload, default(byte[])) and JwtDecoder.Decode(tokenString);

abatishchev commented 1 year ago

Yes, the 3rd parameter verify controls whether the signature is verified. By default it's true.

To make sure it works, try to malform the signature and run with true. Then run with false.

abatishchev commented 1 year ago

Some methods's definitions are legacy and there might not not enough overloads indeed. Please feel free to open a PR and add some more. Contributions are always welcome and I try to review and merge them quickly :)

hanselsen commented 1 year ago

Thanks! The library is very useful.