0

User redirected to my website throw a redirected url from a thirdparty website, I wanted to verify that redirected URL, the thirdparty signs the redirected url using RSA private key using RS256 algorithm then put it as a signature in the url. The redirected url look like:

string redirectUrl = "https://my-domain.com/landservicecallback?state=abcd1234&dealId=xyz5678&expireOn=2006-09-18T00:00:00.000Z&signature=VGhpcyBpcyBhIHNpZ25hdHVyZSB0byB2ZXJ5IHRoaXMgaW5zdGFuY2U%3D&keyId=%3MvJikN0EgR5vNplYFZR50z2G******";

Third Party provided me a documentation(documenation using Nimbus Java lib but I want it in c#) regarding how they want me to verify the signature by generating a signed JWT token from the given redirected url params and a public key.

so what I am doing is below:

first generating JWtPayload from the redirected url data:

        // Set up the JWT payload
        var claims = new[]
        {
            new Claim("partnerUrl", "https://www.my-domain.com"),
            new Claim("dealId", "testDealId"),
            new Claim("expireOn", "2023-02-18T00:00:00.000Z"),
        };
        var payload = new JwtPayload(claims);

After that the documentation asked me to generate JWSHeader with JWSAlgorithm.RS256 and keyId(attached in redirected url, note: its not the public key). This is where I got stuck actually, I can't seems to find a way to replicate following code in my c#

// create JWS header
JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(keyId).build();

// create JWT object
 SignedJWT signedJWT = new SignedJWT(jwsHeader, payload);

I saw a similar lib jose-jwtfor c# but it returns JWT token by providing public key but can't able to do like above.

Note: Also the documentation mentioned that after I got signed JWT object in above steps I need to use public key to build a jwsVerifier and verify the signature given in the url like below:

// create verifier
JWSVerifier jwsVerifier = new RSASSAVerifier(rsaPublicKey);
try {
valid = jwsVerifier.verify(jwsHeader, signedJWT.getSigningInput(), new Base64URL(signature));
} catch (JOSEException e) {
   throw new RuntimeException("Failed to verify signature", e);
}

This encryption mechanism completely new to me so I might be missing to make a workaround in c# for the above code. Any suggestion how can I achieve above solution in c# dot net?

  • Probably the easiest way is to construct the signed token yourself (you seemed to have everything: header data, payload data and the signature) and use the jose-jwt library only for verification (with the public key). But to test this, *full* test data would be needed. Can you post such? Also a link to the documentation would be useful. – Topaco Mar 25 '23 at 11:28
  • @Topaco how can I generate that signed token using payload and header using RS256 algorithm and keyId (not public key) in c#, you have any example code for this? – Fazla Elahi Md Jubayer Mar 25 '23 at 14:53
  • Header and payload are just a few base64url encoded data, see https://jwt.io/ with RS256 as chosen algorithm to get an idea. However, I'm not even sure I understand the problem correctly. So you should post sample data for checking if this approach works (and if possible a link to the documentation). – Topaco Mar 25 '23 at 15:18
  • my concern is how they generate SignedJWT object using only headers and claimsets, as far I have seen we need private rsa key to generate JWT object, how can I do this in c#? @Topaco – Fazla Elahi Md Jubayer Mar 26 '23 at 15:34
  • *...how they generate SignedJWT object using only headers and claimsets...* This is generally not possible (neither in C# nor in any other language). To create a signed token (or a signature in general), a private key is *mandatory*. – Topaco Mar 26 '23 at 16:04
  • For this reason, I suspect that you are not really supposed to create a signed token via JWS, but just *reconstruct* a signed token from header, payload and signature (which you seem to have received). But as I said, without test data / link to the documentation, this guess can't be verified. – Topaco Mar 26 '23 at 16:08
  • @Topaco unfortunately the documentation is not accessible publicly, but I can give you any information you need, so doc ask me to get SignedJWT using this method (https://www.tabnine.com/code/java/methods/com.nimbusds.jose.JWSHeader$Builder/keyID) and then create JWSVerifier jwsVerifier = new RSASSAVerifier(rsaPublicKey); and then validate the signature I received from the url like that: (post in next comment) – Fazla Elahi Md Jubayer Mar 26 '23 at 16:13
  • // verify signature boolean valid; try { valid = jwsVerifier.verify(jwsHeader, signedJWT.getSigningInput(), new Base64URL(signature)); } catch (JOSEException e) { throw new RuntimeException("Failed to verify signature", e); } if (!valid) { throw new RuntimeException("Failed to verify signature"); } @Topaco – Fazla Elahi Md Jubayer Mar 26 '23 at 16:13
  • Your description and the code seem inconsistent to me: The linked code https://www.tabnine.com/code/java/methods/com.nimbusds.jose.JWSHeader$Builder/keyID uses a private key: `new RSASSASigner(credentials.getPrivateKey())`, and generates the signature of header and payload or the signed token via JWS. According to your description you don't have a private key. – Topaco Mar 26 '23 at 16:58

0 Answers0