public void verify() throws IOException, CertificateException { PublicKey publicKey = loadPublicKey(); // Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding"); // cipher.init(Cipher.DECRYPT_MODE, publicKey); // byte[] encryptedbytes = cipher.doFinal(Base64.getUrlDecoder().decode(signatureStr.getBytes())); // String result = Base64.getUrlEncoder().encodeToString(encryptedbytes); // System.out.println("---------------------------------"); // System.out.println(result); // System.out.println(parts[0] + parts[1]); // // System.out.println("---------------------------------"); //TODO: possible decode without 3rd party library... JWTVerifier verifier = JWT.require(Algorithm.RSA256((RSAKey) publicKey)).withIssuer(issuer).build(); DecodedJWT jwt = verifier.verify(token); // System.out.println("DecodedJWT"); // System.out.println(jwt); // System.out.println("---------------------------------"); }
/** * Gets the APK Signature Scheme v2 signature algorithms to be used for signing an APK using the * provided key. * * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see * AndroidManifest.xml minSdkVersion attribute). * * @throws InvalidKeyException if the provided key is not suitable for signing APKs using * APK Signature Scheme v2 */ public static List<SignatureAlgorithm> getSuggestedSignatureAlgorithms( PublicKey signingKey, int minSdkVersion) throws InvalidKeyException { String keyAlgorithm = signingKey.getAlgorithm(); if ("RSA".equalsIgnoreCase(keyAlgorithm)) { // Use RSASSA-PKCS1-v1_5 signature scheme instead of RSASSA-PSS to guarantee // deterministic signatures which make life easier for OTA updates (fewer files // changed when deterministic signature schemes are used). // Pick a digest which is no weaker than the key. int modulusLengthBits = ((RSAKey) signingKey).getModulus().bitLength(); if (modulusLengthBits <= 3072) { // 3072-bit RSA is roughly 128-bit strong, meaning SHA-256 is a good fit. return Collections.singletonList(SignatureAlgorithm.RSA_PKCS1_V1_5_WITH_SHA256); } else { // Keys longer than 3072 bit need to be paired with a stronger digest to avoid the // digest being the weak link. SHA-512 is the next strongest supported digest. return Collections.singletonList(SignatureAlgorithm.RSA_PKCS1_V1_5_WITH_SHA512); } } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) { // DSA is supported only with SHA-256. return Collections.singletonList(SignatureAlgorithm.DSA_WITH_SHA256); } else if ("EC".equalsIgnoreCase(keyAlgorithm)) { // Pick a digest which is no weaker than the key. int keySizeBits = ((ECKey) signingKey).getParams().getOrder().bitLength(); if (keySizeBits <= 256) { // 256-bit Elliptic Curve is roughly 128-bit strong, meaning SHA-256 is a good fit. return Collections.singletonList(SignatureAlgorithm.ECDSA_WITH_SHA256); } else { // Keys longer than 256 bit need to be paired with a stronger digest to avoid the // digest being the weak link. SHA-512 is the next strongest supported digest. return Collections.singletonList(SignatureAlgorithm.ECDSA_WITH_SHA512); } } else { throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm); } }
/** * * @param kpair test key pair * @param pubExponent expected public exponent. * @return true if test passed. false if test failed. */ private static boolean specTest(KeyPair kpair, BigInteger pubExponent) { boolean passed = true; RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate(); RSAPublicKey pub = (RSAPublicKey) kpair.getPublic(); // test the getModulus method if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) { if (!priv.getModulus().equals(pub.getModulus())) { System.err.println("priv.getModulus() = " + priv.getModulus()); System.err.println("pub.getModulus() = " + pub.getModulus()); passed = false; } if (!pubExponent.equals(pub.getPublicExponent())) { System.err.println("pubExponent = " + pubExponent); System.err.println("pub.getPublicExponent() = " + pub.getPublicExponent()); passed = false; } } return passed; }
@Test public void shouldDoRSA256Signing() throws Exception { Algorithm algorithmSign = Algorithm.RSA256((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); Algorithm algorithmVerify = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); String jwtContent = String.format("%s.%s", RS256Header, auth0IssPayload); byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); byte[] signatureBytes = algorithmSign.sign(contentBytes); String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); String token = String.format("%s.%s", jwtContent, jwtSignature); String expectedSignature = "ZB-Tr0vLtnf8I9fhSdSjU6HZei5xLYZQ6nZqM5O6Va0W9PgAqgRT7ShI9CjeYulRXPHvVmSl5EQuYuXdBzM0-H_3p_Nsl6tSMy4EyX2kkhEm6T0HhvarTh8CG0PCjn5p6FP5ZxWwhLcmRN70ItP6Z5MMO4CcJh1JrNxR4Fi4xQgt-CK2aVDMFXd-Br5yQiLVx1CX83w28OD9wssW3Rdltl5e66vCef0Ql6Q5I5e5F0nqGYT989a9fkNgLIx2F8k_az5x07BY59FV2SZg59nSiY7TZNjP8ot11Ew7HKRfPXOdh9eKRUVdhcxzqDePhyzKabU8TG5FP0SiWH5qVPfAgw"; assertThat(signatureBytes, is(notNullValue())); assertThat(jwtSignature, is(expectedSignature)); JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithmVerify.verify(decoded, EncodeType.Base64); }
@Test public void shouldDoRSA384Signing() throws Exception { Algorithm algorithmSign = Algorithm.RSA384((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); Algorithm algorithmVerify = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); String jwtContent = String.format("%s.%s", RS384Header, auth0IssPayload); byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); byte[] signatureBytes = algorithmSign.sign(contentBytes); String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); String token = String.format("%s.%s", jwtContent, jwtSignature); String expectedSignature = "Jx1PaTBnjd_U56MNjifFcY7w9ImDbseg0y8Ijr2pSiA1_wzQb_wy9undaWfzR5YqdIAXvjS8AGuZUAzIoTG4KMgOgdVyYDz3l2jzj6wI-lgqfR5hTy1w1ruMUQ4_wobpdxAiJ4fEbg8Mi_GljOiCO-P1HilxKnpiOJZidR8MQGwTInsf71tOUkK4x5UsdmUueuZbaU-CL5kPnRfXmJj9CcdxZbD9oMlbo23dwkP5BNMrS2LwGGzc9C_-ypxrBIOVilG3WZxcSmuG86LjcZbnL6LBEfph5NmKBgQav147uipb_7umBEr1m2dYiB_9u606n3bcoo3rnsYYK_Xfi1GAEQ"; assertThat(signatureBytes, is(notNullValue())); assertThat(jwtSignature, is(expectedSignature)); JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithmVerify.verify(decoded, EncodeType.Base64); }
@Test public void shouldDoRSA512Signing() throws Exception { Algorithm algorithmSign = Algorithm.RSA512((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); Algorithm algorithmVerify = Algorithm.RSA512((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); String jwtContent = String.format("%s.%s", RS512Header, auth0IssPayload); byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); byte[] signatureBytes = algorithmSign.sign(contentBytes); String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); String token = String.format("%s.%s", jwtContent, jwtSignature); String expectedSignature = "THIPVYzNZ1Yo_dm0k1UELqV0txs3SzyMopCyHcLXOOdgYXF4MlGvBqu0CFvgSga72Sp5LpuC1Oesj40v_QDsp2GTGDeWnvvcv_eo-b0LPSpmT2h1Ibrmu-z70u2rKf28pkN-AJiMFqi8sit2kMIp1bwIVOovPvMTQKGFmova4Xwb3G526y_PeLlflW1h69hQTIVcI67ACEkAC-byjDnnYIklA-B4GWcggEoFwQRTdRjAUpifA6HOlvnBbZZlUd6KXwEydxVS-eh1odwPjB2_sfbyy5HnLsvNdaniiZQwX7QbwLNT4F72LctYdHHM1QCrID6bgfgYp9Ij9CRX__XDEA"; assertThat(signatureBytes, is(notNullValue())); assertThat(jwtSignature, is(expectedSignature)); JWT jwt = JWT.require(algorithmVerify).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithmVerify.verify(decoded, EncodeType.Base64); }
private static byte[] sign() throws Exception { RSAEngine rsa = new RSAEngine(); Digest dig = new SHA1Digest(); RSAPrivateKey privateKey = (RSAPrivateKey) getPrivate(privateKeyFilename); BigInteger big = ((RSAKey) privateKey).getModulus(); ISO9796d2Signer eng = new ISO9796d2Signer(rsa, dig, true); RSAKeyParameters rsaPriv = new RSAKeyParameters(true, big, privateKey.getPrivateExponent()); eng.init(true, rsaPriv); eng.update(message[0]); eng.update(message, 1, message.length - 1); byte[] signature = eng.generateSignature(); return signature; }
/** * * @param kpair test key pair * @param pubExponent expected public exponent. * @return true if test passed. false if test failed. */ private static boolean specTest(KeyPair kpair, BigInteger pubExponent) { boolean passed = true; RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate(); RSAPublicKey pub = (RSAPublicKey) kpair.getPublic(); // test the getModulus method if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) { if (!priv.getModulus().equals(pub.getModulus())) { System.out.println("priv.getModulus() = " + priv.getModulus()); System.out.println("pub.getModulus() = " + pub.getModulus()); passed = false; } if (!pubExponent.equals(pub.getPublicExponent())) { System.out.println("pubExponent = " + pubExponent); System.out.println("pub.getPublicExponent() = " + pub.getPublicExponent()); passed = false; } } return passed; }
private DecodedJWT verifyToken(String idToken) throws JwkException { if (verifier != null) { return verifier.verify(idToken); } if (algorithm != null) { verifier = JWT.require(algorithm) .withAudience(audience) .withIssuer(issuer) .build(); return verifier.verify(idToken); } String kid = JWT.decode(idToken).getKeyId(); PublicKey publicKey = jwkProvider.get(kid).getPublicKey(); return JWT.require(Algorithm.RSA256((RSAKey) publicKey)) .withAudience(audience) .withIssuer(issuer) .build() .verify(idToken); }
/** * Wraps the provided private key for use in the TLS/SSL stack only. Sign/decrypt operations * using the key will be delegated to the {@code Signature}/{@code Cipher} implementation of the * provider which accepts the key. */ static OpenSSLKey wrapJCAPrivateKeyForTLSStackOnly(PrivateKey privateKey, PublicKey publicKey) throws InvalidKeyException { BigInteger modulus = null; if (privateKey instanceof RSAKey) { modulus = ((RSAKey) privateKey).getModulus(); } else if (publicKey instanceof RSAKey) { modulus = ((RSAKey) publicKey).getModulus(); } if (modulus == null) { throw new InvalidKeyException("RSA modulus not available. Private: " + privateKey + ", public: " + publicKey); } return new OpenSSLKey( NativeCrypto.getRSAPrivateKeyWrapper(privateKey, modulus.toByteArray()), true); }
/** * Get the key size of a public key. * * @param pubKey The public key * @return The key size, {@link #UNKNOWN_KEY_SIZE} if not known */ public static int getKeyLength(PublicKey pubKey) { if (pubKey instanceof RSAKey) { return ((RSAKey) pubKey).getModulus().bitLength(); } else if (pubKey instanceof DSAKey) { return ((DSAKey) pubKey).getParams().getP().bitLength(); } else if (pubKey instanceof DHKey) { return ((DHKey) pubKey).getParams().getP().bitLength(); } else if (pubKey instanceof ECKey) { // TODO: how to get key size from these? return UNKNOWN_KEY_SIZE; } LOG.warning("Don't know how to get key size from key " + pubKey); return UNKNOWN_KEY_SIZE; }
@Test public void shouldFailToAuthenticateUsingInvalidJWK() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair1 = RSAKeyPair(); KeyPair keyPair2 = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenReturn(jwk); when(jwk.getPublicKey()).thenReturn(keyPair1.getPublic()); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("audience") .withIssuer("issuer") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair2.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(BadCredentialsException.class); exception.expectMessage("Not a valid token"); exception.expectCause(Matchers.<Throwable>instanceOf(SignatureVerificationException.class)); provider.authenticate(authentication); }
@Test public void shouldFailToAuthenticateUsingJWKIfMissingAudienceClaim() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenReturn(jwk); when(jwk.getPublicKey()).thenReturn(keyPair.getPublic()); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withIssuer("issuer") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(BadCredentialsException.class); exception.expectMessage("Not a valid token"); exception.expectCause(Matchers.<Throwable>instanceOf(InvalidClaimException.class)); provider.authenticate(authentication); }
@Test public void shouldFailToAuthenticateUsingJWKIfMissingIssuerClaim() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenReturn(jwk); when(jwk.getPublicKey()).thenReturn(keyPair.getPublic()); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("audience") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(BadCredentialsException.class); exception.expectMessage("Not a valid token"); exception.expectCause(Matchers.<Throwable>instanceOf(InvalidClaimException.class)); provider.authenticate(authentication); }
@Test public void shouldFailToAuthenticateUsingJWKIfMissingKeyIdClaim() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenReturn(jwk); when(jwk.getPublicKey()).thenReturn(keyPair.getPublic()); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); String token = JWT.create() .withAudience("some") .withIssuer("issuer") .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(BadCredentialsException.class); exception.expectMessage("No kid found in jwt"); provider.authenticate(authentication); }
@Test public void shouldFailToAuthenticateUsingJWKIfIssuerClaimDoesNotMatch() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenReturn(jwk); when(jwk.getPublicKey()).thenReturn(keyPair.getPublic()); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("audience") .withIssuer("some") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(BadCredentialsException.class); exception.expectMessage("Not a valid token"); exception.expectCause(Matchers.<Throwable>instanceOf(InvalidClaimException.class)); provider.authenticate(authentication); }
@Test public void shouldFailToAuthenticateUsingJWKIfAudienceClaimDoesNotMatch() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenReturn(jwk); when(jwk.getPublicKey()).thenReturn(keyPair.getPublic()); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("some") .withIssuer("issuer") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(BadCredentialsException.class); exception.expectMessage("Not a valid token"); exception.expectCause(Matchers.<Throwable>instanceOf(InvalidClaimException.class)); provider.authenticate(authentication); }
@SuppressWarnings("ConstantConditions") @Test public void shouldFailToAuthenticateUsingJWKIfMissingProvider() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = null; KeyPair keyPair = RSAKeyPair(); when(jwk.getPublicKey()).thenReturn(keyPair.getPublic()); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("audience") .withIssuer("issuer") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(AuthenticationServiceException.class); exception.expectMessage("Missing jwk provider"); provider.authenticate(authentication); }
@SuppressWarnings("unchecked") @Test public void shouldFailToAuthenticateUsingJWKIfKeyIdDoesNotMatch() throws Exception { JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenThrow(SigningKeyNotFoundException.class); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("some") .withIssuer("issuer") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(AuthenticationServiceException.class); exception.expectMessage("Could not retrieve jwks from issuer"); exception.expectCause(Matchers.<Throwable>instanceOf(SigningKeyNotFoundException.class)); provider.authenticate(authentication); }
@SuppressWarnings("unchecked") @Test public void shouldFailToAuthenticateUsingJWKIfPublicKeyIsInvalid() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenReturn(jwk); when(jwk.getPublicKey()).thenThrow(InvalidPublicKeyException.class); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("some") .withIssuer("issuer") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(AuthenticationServiceException.class); exception.expectMessage("Could not retrieve public key from issuer"); exception.expectCause(Matchers.<Throwable>instanceOf(InvalidPublicKeyException.class)); provider.authenticate(authentication); }
@SuppressWarnings("unchecked") @Test public void shouldFailToAuthenticateUsingJWKIfKeyIdCannotBeObtained() throws Exception { JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenThrow(JwkException.class); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("some") .withIssuer("issuer") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); exception.expect(AuthenticationServiceException.class); exception.expectMessage("Cannot authenticate with jwt"); exception.expectCause(Matchers.<Throwable>instanceOf(JwkException.class)); provider.authenticate(authentication); }
@Test public void shouldAuthenticateUsingJWK() throws Exception { Jwk jwk = mock(Jwk.class); JwkProvider jwkProvider = mock(JwkProvider.class); KeyPair keyPair = RSAKeyPair(); when(jwkProvider.get(eq("key-id"))).thenReturn(jwk); when(jwk.getPublicKey()).thenReturn(keyPair.getPublic()); JwtAuthenticationProvider provider = new JwtAuthenticationProvider(jwkProvider, "issuer", "audience"); Map<String, Object> keyIdHeader = Collections.singletonMap("kid", (Object) "key-id"); String token = JWT.create() .withAudience("audience") .withIssuer("issuer") .withHeader(keyIdHeader) .sign(Algorithm.RSA256((RSAKey) keyPair.getPrivate())); Authentication authentication = PreAuthenticatedAuthenticationJsonWebToken.usingToken(token); Authentication result = provider.authenticate(authentication); assertThat(result, is(notNullValue())); assertThat(result, is(not(equalTo(authentication)))); }
@Test public void shouldDoRSA256Signing() throws Exception { Algorithm algorithmSign = Algorithm.RSA256((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); Algorithm algorithmVerify = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); String jwtContent = String.format("%s.%s", RS256Header, auth0IssPayload); byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); byte[] signatureBytes = algorithmSign.sign(contentBytes); String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); String jwt = String.format("%s.%s", jwtContent, jwtSignature); String expectedSignature = "ZB-Tr0vLtnf8I9fhSdSjU6HZei5xLYZQ6nZqM5O6Va0W9PgAqgRT7ShI9CjeYulRXPHvVmSl5EQuYuXdBzM0-H_3p_Nsl6tSMy4EyX2kkhEm6T0HhvarTh8CG0PCjn5p6FP5ZxWwhLcmRN70ItP6Z5MMO4CcJh1JrNxR4Fi4xQgt-CK2aVDMFXd-Br5yQiLVx1CX83w28OD9wssW3Rdltl5e66vCef0Ql6Q5I5e5F0nqGYT989a9fkNgLIx2F8k_az5x07BY59FV2SZg59nSiY7TZNjP8ot11Ew7HKRfPXOdh9eKRUVdhcxzqDePhyzKabU8TG5FP0SiWH5qVPfAgw"; assertThat(signatureBytes, is(notNullValue())); assertThat(jwtSignature, is(expectedSignature)); algorithmVerify.verify(JWT.decode(jwt)); }
@Test public void shouldDoRSA384Signing() throws Exception { Algorithm algorithmSign = Algorithm.RSA384((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); Algorithm algorithmVerify = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); String jwtContent = String.format("%s.%s", RS384Header, auth0IssPayload); byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); byte[] signatureBytes = algorithmSign.sign(contentBytes); String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); String jwt = String.format("%s.%s", jwtContent, jwtSignature); String expectedSignature = "Jx1PaTBnjd_U56MNjifFcY7w9ImDbseg0y8Ijr2pSiA1_wzQb_wy9undaWfzR5YqdIAXvjS8AGuZUAzIoTG4KMgOgdVyYDz3l2jzj6wI-lgqfR5hTy1w1ruMUQ4_wobpdxAiJ4fEbg8Mi_GljOiCO-P1HilxKnpiOJZidR8MQGwTInsf71tOUkK4x5UsdmUueuZbaU-CL5kPnRfXmJj9CcdxZbD9oMlbo23dwkP5BNMrS2LwGGzc9C_-ypxrBIOVilG3WZxcSmuG86LjcZbnL6LBEfph5NmKBgQav147uipb_7umBEr1m2dYiB_9u606n3bcoo3rnsYYK_Xfi1GAEQ"; assertThat(signatureBytes, is(notNullValue())); assertThat(jwtSignature, is(expectedSignature)); algorithmVerify.verify(JWT.decode(jwt)); }
@Test public void shouldDoRSA512Signing() throws Exception { Algorithm algorithmSign = Algorithm.RSA512((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); Algorithm algorithmVerify = Algorithm.RSA512((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); String jwtContent = String.format("%s.%s", RS512Header, auth0IssPayload); byte[] contentBytes = jwtContent.getBytes(StandardCharsets.UTF_8); byte[] signatureBytes = algorithmSign.sign(contentBytes); String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes); String jwt = String.format("%s.%s", jwtContent, jwtSignature); String expectedSignature = "THIPVYzNZ1Yo_dm0k1UELqV0txs3SzyMopCyHcLXOOdgYXF4MlGvBqu0CFvgSga72Sp5LpuC1Oesj40v_QDsp2GTGDeWnvvcv_eo-b0LPSpmT2h1Ibrmu-z70u2rKf28pkN-AJiMFqi8sit2kMIp1bwIVOovPvMTQKGFmova4Xwb3G526y_PeLlflW1h69hQTIVcI67ACEkAC-byjDnnYIklA-B4GWcggEoFwQRTdRjAUpifA6HOlvnBbZZlUd6KXwEydxVS-eh1odwPjB2_sfbyy5HnLsvNdaniiZQwX7QbwLNT4F72LctYdHHM1QCrID6bgfgYp9Ij9CRX__XDEA"; assertThat(signatureBytes, is(notNullValue())); assertThat(jwtSignature, is(expectedSignature)); algorithmVerify.verify(JWT.decode(jwt)); }
@Test public void testClaimsAndVerifyRsa() throws Exception { final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); final KeyPair pair = keyGen.generateKeyPair(); final RSAKey privateKey = (RSAKey) pair.getPrivate(); final RSAKey publicKey = (RSAKey) pair.getPublic(); token = JWT.create() .withArrayClaim("roles", new String[]{"Role1", "Role2"}) .withClaim("uid", 1) .withClaim("name", "admin") .withClaim("url", "http://test.com") .withIssuedAt(Date.from(LocalDateTime.now().toInstant(offset))) .withExpiresAt(Date.from(LocalDateTime.now().plusHours(2).toInstant(offset))) .sign(Algorithm.RSA512(privateKey)); final Verifier verifier = Verifier.create(token); assertEquals(1, verifier.getUid()); assertEquals("admin", verifier.getName()); assertEquals("http://test.com", verifier.getUrl()); final List<String> roles = verifier.getRoles(); assertEquals(2, roles.size()); assertEquals("Role1", roles.get(0)); assertEquals("Role2", roles.get(1)); assertTrue(verifier.verify(Algorithm.RSA512(publicKey))); assertFalse(verifier.verify(Algorithm.RSA512((RSAKey) keyGen.genKeyPair().getPublic()))); }
private static Algorithm getAlgorithm(String algo, String key, boolean IsKeyASignerKey) throws IllegalArgumentException, UnsupportedEncodingException { if (algo.equals(HS256.getAlgorithm())) { return Algorithm.HMAC256(key); } if (algo.equals(HS384.getAlgorithm())) { return Algorithm.HMAC384(key); } if (algo.equals(HS512.getAlgorithm())) { return Algorithm.HMAC512(key); } if (algo.equals(ES256.getAlgorithm())) { return Algorithm.ECDSA256((ECKey) getKeyInstance(key, "EC", IsKeyASignerKey)); } if (algo.equals(ES384.getAlgorithm())) { return Algorithm.ECDSA384((ECKey) getKeyInstance(key, "EC", IsKeyASignerKey)); } if (algo.equals(ES512.getAlgorithm())) { return Algorithm.ECDSA512((ECKey) getKeyInstance(key, "EC",IsKeyASignerKey)); } if (algo.equals(RS256.getAlgorithm())) { return Algorithm.RSA256((RSAKey) getKeyInstance(key, "RSA", IsKeyASignerKey)); } if (algo.equals(RS384.getAlgorithm())) { return Algorithm.RSA384((RSAKey) getKeyInstance(key, "RSA", IsKeyASignerKey)); } if (algo.equals(RS512.getAlgorithm())) { return Algorithm.RSA512((RSAKey) getKeyInstance(key, "RSA", IsKeyASignerKey)); } return Algorithm.none(); }
/** * @param kpair test key pair. * @return true if test passed. false if test failed. */ private static boolean sizeTest(KeyPair kpair) { RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate(); RSAPublicKey pub = (RSAPublicKey) kpair.getPublic(); // test the getModulus method if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) { if (!priv.getModulus().equals(pub.getModulus())) { System.err.println("priv.getModulus() = " + priv.getModulus()); System.err.println("pub.getModulus() = " + pub.getModulus()); return false; } } return true; }
@Test public void shouldPassRSA256Verification() throws Exception { String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; Algorithm algorithm = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithm.verify(decoded, EncodeType.Base64); }
@Test public void shouldFailRSA256VerificationWithInvalidPublicKey() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withRSA"); String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; Algorithm algorithm = Algorithm.RSA256((RSAKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE, "RSA")); JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithm.verify(decoded, EncodeType.Base64); }
@Test public void shouldFailRSA256VerificationWhenUsingPrivateKey() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withRSA"); exception.expectCause(isA(IllegalStateException.class)); exception.expectCause(hasMessage(is("The given Public Key is null."))); String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.dxXF3MdsyW-AuvwJpaQtrZ33fAde9xWxpLIg9cO2tMLH2GSRNuLAe61KsJusZhqZB9Iy7DvflcmRz-9OZndm6cj_ThGeJH2LLc90K83UEvvRPo8l85RrQb8PcanxCgIs2RcZOLygERizB3pr5icGkzR7R2y6zgNCjKJ5_NJ6EiZsGN6_nc2PRK_DbyY-Wn0QDxIxKoA5YgQJ9qafe7IN980pXvQv2Z62c3XR8dYuaXBqhthBj-AbaFHEpZapN-V-TmuLNzR2MCB6Xr7BYMuCaqWf_XU8og4XNe8f_8w9Wv5vvgqMM1KhqVpG5VdMJv4o_L4NoCROHhtUQSLRh2M9cA"; Algorithm algorithm = Algorithm.RSA256((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithm.verify(decoded, EncodeType.Base64); }
@Test public void shouldPassRSA384Verification() throws Exception { String token = "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.TZlWjXObwGSQOiu2oMq8kiKz0_BR7bbBddNL6G8eZ_GoR82BXOZDqNrQr7lb_M-78XGBguWLWNIdYhzgxOUL9EoCJlrqVm9s9vo6G8T1sj1op-4TbjXZ61TwIvrJee9BvPLdKUJ9_fp1Js5kl6yXkst40Th8Auc5as4n49MLkipjpEhKDKaENKHpSubs1ripSz8SCQZSofeTM_EWVwSw7cpiM8Fy8jOPvWG8Xz4-e3ODFowvHVsDcONX_4FTMNbeRqDuHq2ZhCJnEfzcSJdrve_5VD5fM1LperBVslTrOxIgClOJ3RmM7-WnaizJrWP3D6Z9OLxPxLhM6-jx6tcxEw"; Algorithm algorithm = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithm.verify(decoded, EncodeType.Base64); }
@Test public void shouldFailRSA384VerificationWithInvalidPublicKey() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withRSA"); String token = "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.TZlWjXObwGSQOiu2oMq8kiKz0_BR7bbBddNL6G8eZ_GoR82BXOZDqNrQr7lb_M-78XGBguWLWNIdYhzgxOUL9EoCJlrqVm9s9vo6G8T1sj1op-4TbjXZ61TwIvrJee9BvPLdKUJ9_fp1Js5kl6yXkst40Th8Auc5as4n49MLkipjpEhKDKaENKHpSubs1ripSz8SCQZSofeTM_EWVwSw7cpiM8Fy8jOPvWG8Xz4-e3ODFowvHVsDcONX_4FTMNbeRqDuHq2ZhCJnEfzcSJdrve_5VD5fM1LperBVslTrOxIgClOJ3RmM7-WnaizJrWP3D6Z9OLxPxLhM6-jx6tcxEw"; Algorithm algorithm = Algorithm.RSA384((RSAKey) readPublicKeyFromFile(INVALID_PUBLIC_KEY_FILE, "RSA")); JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithm.verify(decoded, EncodeType.Base64); }
@Test public void shouldFailRSA384VerificationWhenUsingPrivateKey() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA384withRSA"); exception.expectCause(isA(IllegalStateException.class)); exception.expectCause(hasMessage(is("The given Public Key is null."))); String token = "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.TZlWjXObwGSQOiu2oMq8kiKz0_BR7bbBddNL6G8eZ_GoR82BXOZDqNrQr7lb_M-78XGBguWLWNIdYhzgxOUL9EoCJlrqVm9s9vo6G8T1sj1op-4TbjXZ61TwIvrJee9BvPLdKUJ9_fp1Js5kl6yXkst40Th8Auc5as4n49MLkipjpEhKDKaENKHpSubs1ripSz8SCQZSofeTM_EWVwSw7cpiM8Fy8jOPvWG8Xz4-e3ODFowvHVsDcONX_4FTMNbeRqDuHq2ZhCJnEfzcSJdrve_5VD5fM1LperBVslTrOxIgClOJ3RmM7-WnaizJrWP3D6Z9OLxPxLhM6-jx6tcxEw"; Algorithm algorithm = Algorithm.RSA384((RSAKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE, "RSA")); JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithm.verify(decoded, EncodeType.Base64); }
@Test public void shouldPassRSA512Verification() throws Exception { String token = "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhdXRoMCJ9.mvL5LoMyIrWYjk5umEXZTmbyIrkbbcVPUkvdGZbu0qFBxGOf0nXP5PZBvPcOu084lvpwVox5n3VaD4iqzW-PsJyvKFgi5TnwmsbKchAp7JexQEsQOnTSGcfRqeUUiBZqRQdYsho71oAB3T4FnalDdFEpM-fztcZY9XqKyayqZLreTeBjqJm4jfOWH7KfGBHgZExQhe96NLq1UA9eUyQwdOA1Z0SgXe4Ja5PxZ6Fm37KnVDtDlNnY4JAAGFo6y74aGNnp_BKgpaVJCGFu1f1S5xCQ1HSvs8ZSdVWs5NgawW3wRd0kRt_GJ_Y3mIwiF4qUyHWGtsSHu_qjVdCTtbFyow"; Algorithm algorithm = Algorithm.RSA512((RSAKey) readPublicKeyFromFile(PUBLIC_KEY_FILE, "RSA")); JWT jwt = JWT.require(algorithm).withIssuer("auth0").build(); DecodedJWT decoded = jwt.decode(token); algorithm.verify(decoded, EncodeType.Base64); }