title: Validating Azure AD Token signature fails JAVA
body: <p>I am struggling to validate an Azure AD token signature.</p>
  
  <p>When I look up the correct key description in the "jwks_uri" field under</p>
  
  <p><a href="https://login.microsoftonline.com/common/.well-known/openid-configuration" rel="noreferrer">https://login.microsoftonline.com/common/.well-known/openid-configuration</a></p>
  
  <p>I check the belonging key data .</p>
  
  <p>I try to use the "n" - modulus and "e" fields to generate the public key for the signature validation I end up with an error:</p>
  
  <pre><code>BASE64Decoder decoder = new BASE64Decoder();        
  byte[] modulusBytes = decoder.decodeBuffer(n);
  byte[] exponentBytes = decoder.decodeBuffer(e);
  
  BigInteger modulusInt = new BigInteger(1, modulusBytes);
  BigInteger exponentInt = new BigInteger(1, exponentBytes);
  
  try {
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(modulusInt, exponentInt);
  RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(publicSpec);
  Jwt&lt;Header, String&gt; c = Jwts.parser().setSigningKey(pubKey).parsePlaintextJwt(token);
  
  } catch (Exception ex) {
    ex.printStackTrace();
  }
  </code></pre>
  
  <p>Console:</p>
  
  <pre><code>io.jsonwebtoken.SignatureException: Unable to verify RSA signature using configured PublicKey. Signature length not correct: got 256 but was expecting 246
  at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.isValid(RsaSignatureValidator.java:50)
  at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.isValid(DefaultJwtSignatureValidator.java:47)
  at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:351)
  at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481)
  at io.jsonwebtoken.impl.DefaultJwtParser.parsePlaintextJwt(DefaultJwtParser.java:503)
  at com.ge.hc.pfh.poc.ams.filter.JwtFilter.doFilter(JwtFilter.java:120)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at com.ge.hc.pfh.poc.ams.filter.ApiOriginFIlter.doFilter(ApiOriginFIlter.java:28)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at com.ge.hc.pfh.poc.ams.filter.MDCFilter.doFilter(MDCFilter.java:34)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
  at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784)
  at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
  at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)
  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410)
  at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p>I tried another approach to use the "x5c" filed which is a base 64 encoded cert chain:</p>
  
  <pre><code>byte[] certChain = Base64.getDecoder().decode(x5c);
  X509Certificate cert = X509CertUtils.parse(certChain);
  PublicKey pubKeyNew = cert.getPublicKey();
  Claims claims3 = Jwts.parser()
            .setSigningKey(pubKeyNew)
              .parseClaimsJws(token).getBody();
  </code></pre>
  
  <p>I end up with an other error:</p>
  
  <pre><code>io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
  at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:354)
  at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481)
  at io.jsonwebtoken.impl.DefaultJwtParser.parsePlaintextJwt(DefaultJwtParser.java:503)
  at com.ge.hc.pfh.poc.ams.filter.JwtFilter.doFilter(JwtFilter.java:106)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at com.ge.hc.pfh.poc.ams.filter.ApiOriginFIlter.doFilter(ApiOriginFIlter.java:28)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at com.ge.hc.pfh.poc.ams.filter.MDCFilter.doFilter(MDCFilter.java:34)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
  at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784)
  at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
  at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)
  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410)
  at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p>Would anyone know what I am doing wrong?
  Thanks.</p>