uruk-project / Jwt

JSON Web Token implementation for .Net & .Net Core
MIT License
85 stars 11 forks source link

Encrypted key present in ECDH-ES algorithm results in Invalid JWE #578

Closed greg-signi closed 1 year ago

greg-signi commented 1 year ago

Hello, should there be a encrypted key present when using this algorithm ?

According to my readings, this algorithm uses Direct Key Agreement, and when using this it seems that the JWE Encrypted key value should have been empty ? https://datatracker.ietf.org/doc/html/rfc7516#section-5.2 (10)

It's turning out to be a invalid JWE, since in the CEK part we are getting ".AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA." instead of the empty octet ?

Example:

string json = "{\r\n        \"alg\": \"ES256\",\r\n        \"crv\": \"P-256\",\r\n        \"kty\": \"EC\",\r\n        \"use\": \"sig\",\r\n        \"x\": \"OKs1T_4N9Z78RQ87olZ98PW__ROFWL5fw1671XB20zw\",\r\n        \"y\": \"8y5YBG5RY4gK2bObN4Aj5eNmXBoLMrCHKEMwykPSTIg\"\r\n      }";
string payload = "teste";

var descriptor = new PlaintextJweDescriptor(payload)
{
    EncryptionKey = Jwk.FromJson(json),
    EncryptionAlgorithm = EncryptionAlgorithm.Aes256Gcm,
    Algorithm = KeyManagementAlgorithm.EcdhEs
};

var writer = new JwtWriter();
string jwe = writer.WriteTokenString(descriptor);

Console.WriteLine(jwe);

eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiRUNESC1FUyIsImVwayI6eyJjcnYiOiJQLTI1NiIsIngiOiJNQnpzbF9VM2ZFemxLMzVvbWh4TjlOd05yRm11ZXlRRGR2WUVxd2hENWtnIiwieSI6Ilc1TnJvZGxvQXdTbHptUjZ3cVAwZjVxRHBEQ2NqM0Y0YXEteUNwS1p5a3cifX0.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.2JvH70MzlecMiZtG.Fy85KTI.dHuw2Cw7_im2TAP_YpKrfQ

Thanks in advance @ycrumeyrolle

ycrumeyrolle commented 1 year ago

At first glance, we have a key with zero bytes of n-length instead of an empty key. I will see to fix this weekend.

greg-signi commented 1 year ago

Super! Btw observing the descriptor, noticed the json deserialization appears to fail for the key

image

Edit: Actually nevermind, the fields of the Key are there, I don't know why it's printing that 🤷

ycrumeyrolle commented 1 year ago

@greg-signi fixed in https://www.nuget.org/packages/JsonWebToken/1.9.4

greg-signi commented 1 year ago

Hello, thanks for the reply, I'll test this soon

greg-signi commented 1 year ago

@ycrumeyrolle indeed cek is empty now. Should the jwe generated appear as valid pasting it in jwt.io ?

ycrumeyrolle commented 1 year ago

Jwt.io supports only JWS (3 Base64 parts separated by '.'), not JWE (4 Base64 parts separated by '.')

The issue was that the second part, when it is a direct encryption algorithm, must be an empty part.

greg-signi commented 1 year ago

I see thanks. Can I decrypt now the JWE with your library using my private key in json, or for that I will need to try and find another way to test the decryption ? Huge thanks, our client will be happy w/ this fix.

ycrumeyrolle commented 1 year ago

https://github.com/uruk-project/Jwt/blob/35866ddacbdfd85cdd7bde39c015e02449a52946/test/JsonWebToken.Tests/JweEllipticCurveTokenTests.cs#L38-L47

In this example, _bobKey is the private key for decryption. _signingKey is the signing key for the JWS as payload wrapped within the JWE.

If the Payload is just byte[] or string, the last one is not required.

greg-signi commented 1 year ago

Yep working as intended, thanks for the support. Massive thumbs up 👍 👍