@Test(expected = SignatureException.class) public void shouldNotParse_rsa_wrongSignature() throws Exception { RSAKey rsaJWK = new RSAKeyGenerator(2048) .keyID("123") .generate(); RSAPrivateKey rsaPrivateKey = rsaJWK.toRSAPrivateKey(); RSAKey wrongRsaJWK = new RSAKeyGenerator(2048) .keyID("456") .generate(); RSAPublicKey wrongRsaPublicKey = wrongRsaJWK.toRSAPublicKey(); JWTBuilder jwtBuilder = new DefaultJWTBuilder(rsaPrivateKey, SignatureAlgorithm.RS256.getValue(), rsaJWK.getKeyID()); JWTParser jwtParser = new DefaultJWTParser(wrongRsaPublicKey); JWT jwt = new JWT(); jwt.setIss("https: jwt.setSub("alice"); jwt.setIat(Instant.now().getEpochSecond()); jwt.setExp(Instant.now().plus(60, ChronoUnit.MINUTES).getEpochSecond()); String signedJWT = jwtBuilder.sign(jwt); jwtParser.parse(signedJWT); }
@Override public JWT parse(String payload) { try { SignedJWT signedJWT = SignedJWT.parse(payload); boolean verified = signedJWT.verify(verifier); if (!verified) { throw new JOSEException("The signature was not verified"); } Map<String, Object> claims = signedJWT .getPayload() .toJSONObject() .entrySet() .stream() .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); JWT jwt = new JWT(claims); Instant now = Instant.now(); if (jwt.getExp() > 0) { Instant exp = Instant.ofEpochSecond(jwt.getExp()); if (now.isAfter(exp)) { long differenceMillis = now.toEpochMilli() - exp.toEpochMilli(); String msg = "JWT expired at " + exp + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new ExpiredJWTException(msg); } } if (jwt.getNbf() > 0) { Instant nbf = Instant.ofEpochSecond(jwt.getNbf()); if (now.isBefore(nbf)) { long differenceMillis = nbf.toEpochMilli() - now.toEpochMilli(); String msg = "JWT must not be accepted before " + nbf + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new PrematureJWTException(msg); } } return jwt; } catch (ParseException ex) { logger.debug("The following JWT token : {} is malformed", payload); throw new MalformedJWTException("Token is malformed", ex); } catch (ExpiredJWTException ex) { logger.debug("The following JWT token : {} is expired", payload); throw new ExpiredJWTException("Token is expired", ex); } catch (PrematureJWTException ex) { logger.debug("The following JWT token : {} must not be accepted (nbf)", payload); throw new PrematureJWTException("Token must not be accepted (nbf)", ex); } catch (JOSEException ex) { logger.debug("Verifying JWT token signature : {} has failed", payload); throw new SignatureException("Token's signature is invalid", ex); } catch (Exception ex) { logger.error("An error occurs while parsing JWT token : {}", payload, ex); throw ex; } }
DefaultJWTParser implements JWTParser { @Override public JWT parse(String payload) { try { SignedJWT signedJWT = SignedJWT.parse(payload); boolean verified = signedJWT.verify(verifier); if (!verified) { throw new JOSEException("The signature was not verified"); } Map<String, Object> claims = signedJWT .getPayload() .toJSONObject() .entrySet() .stream() .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); JWT jwt = new JWT(claims); Instant now = Instant.now(); if (jwt.getExp() > 0) { Instant exp = Instant.ofEpochSecond(jwt.getExp()); if (now.isAfter(exp)) { long differenceMillis = now.toEpochMilli() - exp.toEpochMilli(); String msg = "JWT expired at " + exp + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new ExpiredJWTException(msg); } } if (jwt.getNbf() > 0) { Instant nbf = Instant.ofEpochSecond(jwt.getNbf()); if (now.isBefore(nbf)) { long differenceMillis = nbf.toEpochMilli() - now.toEpochMilli(); String msg = "JWT must not be accepted before " + nbf + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new PrematureJWTException(msg); } } return jwt; } catch (ParseException ex) { logger.debug("The following JWT token : {} is malformed", payload); throw new MalformedJWTException("Token is malformed", ex); } catch (ExpiredJWTException ex) { logger.debug("The following JWT token : {} is expired", payload); throw new ExpiredJWTException("Token is expired", ex); } catch (PrematureJWTException ex) { logger.debug("The following JWT token : {} must not be accepted (nbf)", payload); throw new PrematureJWTException("Token must not be accepted (nbf)", ex); } catch (JOSEException ex) { logger.debug("Verifying JWT token signature : {} has failed", payload); throw new SignatureException("Token's signature is invalid", ex); } catch (Exception ex) { logger.error("An error occurs while parsing JWT token : {}", payload, ex); throw ex; } } }
DefaultJWTParser implements JWTParser { @Override public JWT parse(String payload) { try { SignedJWT signedJWT = SignedJWT.parse(payload); boolean verified = signedJWT.verify(verifier); if (!verified) { throw new JOSEException("The signature was not verified"); } Map<String, Object> claims = signedJWT .getPayload() .toJSONObject() .entrySet() .stream() .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); JWT jwt = new JWT(claims); Instant now = Instant.now(); if (jwt.getExp() > 0) { Instant exp = Instant.ofEpochSecond(jwt.getExp()); if (now.isAfter(exp)) { long differenceMillis = now.toEpochMilli() - exp.toEpochMilli(); String msg = "JWT expired at " + exp + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new ExpiredJWTException(msg); } } if (jwt.getNbf() > 0) { Instant nbf = Instant.ofEpochSecond(jwt.getNbf()); if (now.isBefore(nbf)) { long differenceMillis = nbf.toEpochMilli() - now.toEpochMilli(); String msg = "JWT must not be accepted before " + nbf + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new PrematureJWTException(msg); } } return jwt; } catch (ParseException ex) { logger.debug("The following JWT token : {} is malformed", payload); throw new MalformedJWTException("Token is malformed", ex); } catch (ExpiredJWTException ex) { logger.debug("The following JWT token : {} is expired", payload); throw new ExpiredJWTException("Token is expired", ex); } catch (PrematureJWTException ex) { logger.debug("The following JWT token : {} must not be accepted (nbf)", payload); throw new PrematureJWTException("Token must not be accepted (nbf)", ex); } catch (JOSEException ex) { logger.debug("Verifying JWT token signature : {} has failed", payload); throw new SignatureException("Token's signature is invalid", ex); } catch (Exception ex) { logger.error("An error occurs while parsing JWT token : {}", payload, ex); throw ex; } } DefaultJWTParser(final Key key); }
DefaultJWTParser implements JWTParser { @Override public JWT parse(String payload) { try { SignedJWT signedJWT = SignedJWT.parse(payload); boolean verified = signedJWT.verify(verifier); if (!verified) { throw new JOSEException("The signature was not verified"); } Map<String, Object> claims = signedJWT .getPayload() .toJSONObject() .entrySet() .stream() .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); JWT jwt = new JWT(claims); Instant now = Instant.now(); if (jwt.getExp() > 0) { Instant exp = Instant.ofEpochSecond(jwt.getExp()); if (now.isAfter(exp)) { long differenceMillis = now.toEpochMilli() - exp.toEpochMilli(); String msg = "JWT expired at " + exp + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new ExpiredJWTException(msg); } } if (jwt.getNbf() > 0) { Instant nbf = Instant.ofEpochSecond(jwt.getNbf()); if (now.isBefore(nbf)) { long differenceMillis = nbf.toEpochMilli() - now.toEpochMilli(); String msg = "JWT must not be accepted before " + nbf + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new PrematureJWTException(msg); } } return jwt; } catch (ParseException ex) { logger.debug("The following JWT token : {} is malformed", payload); throw new MalformedJWTException("Token is malformed", ex); } catch (ExpiredJWTException ex) { logger.debug("The following JWT token : {} is expired", payload); throw new ExpiredJWTException("Token is expired", ex); } catch (PrematureJWTException ex) { logger.debug("The following JWT token : {} must not be accepted (nbf)", payload); throw new PrematureJWTException("Token must not be accepted (nbf)", ex); } catch (JOSEException ex) { logger.debug("Verifying JWT token signature : {} has failed", payload); throw new SignatureException("Token's signature is invalid", ex); } catch (Exception ex) { logger.error("An error occurs while parsing JWT token : {}", payload, ex); throw ex; } } DefaultJWTParser(final Key key); @Override JWT parse(String payload); }
DefaultJWTParser implements JWTParser { @Override public JWT parse(String payload) { try { SignedJWT signedJWT = SignedJWT.parse(payload); boolean verified = signedJWT.verify(verifier); if (!verified) { throw new JOSEException("The signature was not verified"); } Map<String, Object> claims = signedJWT .getPayload() .toJSONObject() .entrySet() .stream() .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); JWT jwt = new JWT(claims); Instant now = Instant.now(); if (jwt.getExp() > 0) { Instant exp = Instant.ofEpochSecond(jwt.getExp()); if (now.isAfter(exp)) { long differenceMillis = now.toEpochMilli() - exp.toEpochMilli(); String msg = "JWT expired at " + exp + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new ExpiredJWTException(msg); } } if (jwt.getNbf() > 0) { Instant nbf = Instant.ofEpochSecond(jwt.getNbf()); if (now.isBefore(nbf)) { long differenceMillis = nbf.toEpochMilli() - now.toEpochMilli(); String msg = "JWT must not be accepted before " + nbf + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds. Allowed clock skew: " + this.allowedClockSkewMillis + " milliseconds."; throw new PrematureJWTException(msg); } } return jwt; } catch (ParseException ex) { logger.debug("The following JWT token : {} is malformed", payload); throw new MalformedJWTException("Token is malformed", ex); } catch (ExpiredJWTException ex) { logger.debug("The following JWT token : {} is expired", payload); throw new ExpiredJWTException("Token is expired", ex); } catch (PrematureJWTException ex) { logger.debug("The following JWT token : {} must not be accepted (nbf)", payload); throw new PrematureJWTException("Token must not be accepted (nbf)", ex); } catch (JOSEException ex) { logger.debug("Verifying JWT token signature : {} has failed", payload); throw new SignatureException("Token's signature is invalid", ex); } catch (Exception ex) { logger.error("An error occurs while parsing JWT token : {}", payload, ex); throw ex; } } DefaultJWTParser(final Key key); @Override JWT parse(String payload);  }