title: Validation of PS256 encoded JWT using C#
body: <p>I've been tasked to validate a JWT token that's been encoded using the PS256 algorithm and for the last two days I've been having trouble with it. I lack knowledge on this subject and I've been chipping away slowly at the problem trying different solutions.</p>
  
  <pre><code>// Encoded
  eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZDEyMzQifQ.eyJpc3MiOiJmb28uYmFyLnRlc3Rpc3N1ZXIiLCJleHAiOjE1NTEyMDEwNjgsImF0X2hhc2giOiJqaFl3c1pyTnZ0dFNYQnR6QVMtWlNnIn0.yJePyxdJWyydG4HM97oQag6ulGKa5Afw-LHYYEXz7lVy8v0IJD0mSO9WtowlWJIeD2Vvthuj71XUfHsgz0LD9rK0VBucJbd_OiIXpbwPUqBcdj82DNLFXDJfCJnUC-Rv8QP7OUVBvLjvBQ6WYMrx1Qnq8xP6qeL_ohKwRmo6EDhZRkYBz9gFhfha1ZlKcnyR73nXdShwy7OmmyiRvVWPBf_GgSsfz8FNNoKySW1MA4tRa7cl3zPlyCnWyLaZ3kcQsmTqarHG--YXSDF5ozZ_Sx6TkunCxrOYzOFNcPyeIWqI84cemM6TgMBw9jhzMCk7Y4Fzxe5KEYJH4GlGA4s4zg
  
  // Header
  {
      "alg": "PS256",
      "typ": "JWT",
      "kid": "kid1234"
  }
  
  // Payload
  {
      "iss": "foo.bar.testissuer",
      "exp": 1551201068,
      "at_hash": "jhYwsZrNvttSXBtzAS-ZSg"
  }
  </code></pre>
  
  <p>I have a working implementation for RS256 encoded JWT which is using the <strong>JWTSecurityTokenHandler</strong> provided in <strong>Microsoft.IdentityModel.Tokens</strong> and <strong>System.IdentityModel.Tokens.Jwt</strong>. For the RS256 implementation I have a <strong>IssuerSigningKeyResolver</strong> that is making custom checks for the kid and supplying the public key</p>
  
  <pre><code>var tokenValidationParameters = new TokenValidationParameters
  {
      ValidIssuer = issuer,
      ValidateLifetime = true,
      RequireSignedTokens = true,
      RequireExpirationTime = true,
      ValidateAudience = false,
      ValidateIssuer = true,
      IssuerSigningKeyResolver = (string token, SecurityToken securityToken, string kid, TokenValidationParameters validationParameters) =&gt;
      {
          // Custom kid checks
  
          var rsa = RSA.Create();
          rsa.ImportParameters(new RSAParameters
          {
              Exponent = Base64UrlEncoder.DecodeBytes(matchingKid.E),
              Modulus = Base64UrlEncoder.DecodeBytes(matchingKid.N),
          });
          latestSecurityKeys.Add(matchingKid.Kid, new RsaSecurityKey(rsa));
  
          var securityKeys = new SecurityKey[1]
          {
              new RsaSecurityKey(rsa)
          };
  
          return securityKeys;
      }
  };
  
  var tokenHandler = new JwtSecurityTokenHandler();
  try
  {
      var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
      return true;
  }
  catch (SecurityTokenException ex)
  {
      // Do something with ex
      return false;
  }
  </code></pre>
  
  <p>This implementation is not working for PS256 encoded JWT. I debugged the <strong><a href="https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/src/System.IdentityModel.Tokens.Jwt/JwtSecurityTokenHandler.cs" rel="nofollow noreferrer">JwtSecurityTokenHandler</a></strong> inside <strong>System.IdentityModel.Tokens.Jwt</strong>, but it seems that even though PS256 is in the supported algorithms list the verification fails.</p>
  
  <p>I must state again that my knowledge on this subject is limited. From what I understand RSA256 and PS256 are in the same family of algorithms? Would I be better off to just create a custom validation of the PS256 JWT using another library like <strong>jose-jwt</strong>?</p>