dvsekhvalnov / jose-jwt

Ultimate Javascript Object Signing and Encryption (JOSE), JSON Web Token (JWT) and Json Web Keys (JWK) Implementation for .NET and .NET Core
MIT License
921 stars 183 forks source link

JWT Token Header #231

Open wicetram opened 10 months ago

wicetram commented 10 months ago

Hello,

I need to encrypt Payload data with a JWK string. I can encrypt using the Nuget package, but I have a problem with the header part of the encrypted JWT data. The required header content should only contain the values "alg" and "kid". However, in all the ways I tried, this header part (at least in C#) always comes with the values "alg" and "typ".

When I encrypt this JWK and Payload data with the Java code I use as an example, I can successfully produce JWT information.

I need your help on this matter. Thanks.

C# JWT Header:

{ "alg": "HS256", "typ": "JWT" }

Java JWT Header:

{ "alg": "HS256", "kid": "7b76e130-73de-4562-9c20-ad5e983e22d8" }

Java: package org.example;

import com.nimbusds.jose.*; import com.nimbusds.jose.crypto.MACSigner; import com.nimbusds.jose.jwk.JWK;

import okhttp3.*;

import java.io.IOException; import java.text.ParseException;

public class Main { public static void main(String[] args) throws ParseException, JOSEException, IOException { String payload = "{\"meta\": {\"id\": \"168bba80-5e69-485e-8d16-2e9750cb9c2e\",\"clientInfo\": [{\"type\": \"serverIp\",\"value\": \"WEB\"}]},\"data\": {\"orderId\": \"\",\"amount\": 2,\"operation\": \"sales\",\"returnUrl\": {\"link\": \"https://\",\"type\": \"web\"},\"customer\": {\"nationalNumber\": \"\",\"gsmNumber\": \"\"},\"paymentOptions\": {\"threeDSecureCheck\": true,\"installmentOnlyForCommercialCard\": true}}}";

    String jwkStr = "{\"kty\":\"oct\",\"kid\":\"28075256-56c8-11ee-8c99-0242ac120002\",\"k\":\"eSvOcX4/NrjfRsShI+KgHw==\",\"alg\":\"HS256\"}";

   final JWK jwk = JWK.parse(jwkStr);

   final JWSObject jws = new JWSObject((
           new JWSHeader.Builder(JWSAlgorithm.HS256).keyID(jwk.getKeyID()).build()),
           new Payload(payload)
           );

    JWSSigner signer = new MACSigner(jwk.toOctetSequenceKey());

    System.out.println("key"+jwk.toOctetSequenceKey());
    jws.sign(signer);

    final String httpBody = jws.serialize();

    System.out.println(httpBody);
}

}

C#:

using Jose; using Newtonsoft.Json; using System.Text;

class Program { static void Main() { var jwtRequest = new TokenRequestDto { Kid = "28075256-56c8-11ee-8c99-0242ac120002", K = "eSvOcX4/NrjfRsShI+KgHw==", Alg = "HS256" };

    var data = "{\"meta\": {\"id\": \"168bba80-5e69-485e-8d16-2e9750cb9c2e\",\"clientInfo\": [{\"type\": \"serverIp\",\"value\": \"WEB\"}]},\"data\": {\"orderId\": \"\",\"amount\": 2,\"operation\": \"sales\",\"returnUrl\": {\"link\": \"https://\",\"type\": \"web\"},\"customer\": {\"nationalNumber\": \"\",\"gsmNumber\": \"\"},\"paymentOptions\": {\"threeDSecureCheck\": true,\"installmentOnlyForCommercialCard\": true}}}";

    var jsonKey = JsonConvert.SerializeObject(jwtRequest);

    byte[] hmacKey = Encoding.UTF8.GetBytes(jwtRequest.K);

    if (hmacKey != null)
    {
        // JWT token oluştur
        string jwtToken = JWT.Encode(data, hmacKey, JwsAlgorithm.HS256);

        Console.WriteLine(jwtToken);
    }
    else
    {
        Console.WriteLine("Error: Unable to create JWT. Check JSON key data.");
    }

    Console.ReadKey();
}

public class TokenRequestDto
{
    public string Kid { get; set; }
    public string K { get; set; }
    public string Alg { get; set; }
}

}

dvsekhvalnov commented 10 months ago

Hi @wicetram , is it what you looking for https://github.com/dvsekhvalnov/jose-jwt#adding-extra-headers ?

Just pass extraHeaders dictionary without typ key inside, it will make it disappear from result.