/** * Creates a new Algorithm instance using SHA384withECDSA. Tokens specify this as "ES384". * * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. * @return a valid ECDSA384 Algorithm. * @throws IllegalArgumentException if the Key Provider is null. */ public static Algorithm ECDSA384(ECDSAKeyProvider keyProvider) throws IllegalArgumentException { return new ECDSAAlgorithm("ES384", "SHA384withECDSA", 48, keyProvider); }
/** * Creates a new Algorithm instance using SHA256withECDSA. Tokens specify this as "ES256". * * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. * @return a valid ECDSA256 Algorithm. * @throws IllegalArgumentException if the Key Provider is null. */ public static Algorithm ECDSA256(ECDSAKeyProvider keyProvider) throws IllegalArgumentException { return new ECDSAAlgorithm("ES256", "SHA256withECDSA", 32, keyProvider); }
/** * Creates a new Algorithm instance using SHA512withECDSA. Tokens specify this as "ES512". * * @param keyProvider the provider of the Public Key and Private Key for the verify and signing instance. * @return a valid ECDSA512 Algorithm. * @throws IllegalArgumentException if the Key Provider is null. */ public static Algorithm ECDSA512(ECDSAKeyProvider keyProvider) throws IllegalArgumentException { return new ECDSAAlgorithm("ES512", "SHA512withECDSA", 66, keyProvider); }
@Test public void shouldReturnSigningKeyIdFromProvider() throws Exception { ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); when(provider.getPrivateKeyId()).thenReturn("keyId"); Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider); assertThat(algorithm.getSigningKeyId(), is("keyId")); }
@Test public void shouldReturnNullSigningKeyIdIfCreatedWithDefaultProvider() throws Exception { ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider); assertThat(algorithm.getSigningKeyId(), is(nullValue())); }
@Test public void shouldReturnSigningKeyIdFromProvider() throws Exception { ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class); when(provider.getPrivateKeyId()).thenReturn("keyId"); Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider); assertThat(algorithm.getSigningKeyId(), is("keyId")); }
@Test public void shouldReturnNullSigningKeyIdIfCreatedWithDefaultProvider() throws Exception { ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider); assertThat(algorithm.getSigningKeyId(), is(nullValue())); }
@Test public void shouldThrowOnSignWhenSignatureAlgorithmDoesNotExists() throws Exception { exception.expect(SignatureGenerationException.class); exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); exception.expectCause(isA(NoSuchAlgorithmException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class), any(byte[].class))) .thenThrow(NoSuchAlgorithmException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8), new byte[0]); }
@Test public void shouldThrowOnSignWhenThePrivateKeyIsInvalid() throws Exception { exception.expect(SignatureGenerationException.class); exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); exception.expectCause(isA(InvalidKeyException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class), any(byte[].class))) .thenThrow(InvalidKeyException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8), new byte[0]); }
@Test public void shouldThrowOnSignWhenTheSignatureIsNotPrepared() throws Exception { exception.expect(SignatureGenerationException.class); exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); exception.expectCause(isA(SignatureException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class), any(byte[].class))) .thenThrow(SignatureException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); algorithm.sign(ES256Header.getBytes(StandardCharsets.UTF_8), new byte[0]); }
@Test public void shouldThrowOnVerifyWhenSignatureAlgorithmDoesNotExists() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg"); exception.expectCause(isA(NoSuchAlgorithmException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(String.class), any(String.class), any(byte[].class))) .thenThrow(NoSuchAlgorithmException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; algorithm.verify(JWT.decode(jwt)); }
@Test public void shouldThrowOnSignWhenSignatureAlgorithmDoesNotExists() throws Exception { exception.expect(SignatureGenerationException.class); exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); exception.expectCause(isA(NoSuchAlgorithmException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class), any(byte[].class))) .thenThrow(NoSuchAlgorithmException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); algorithm.sign(ES256HeaderBytes, new byte[0]); }
@Test public void shouldThrowOnVerifyWhenThePublicKeyIsInvalid() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg"); exception.expectCause(isA(InvalidKeyException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(String.class), any(String.class), any(byte[].class))) .thenThrow(InvalidKeyException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; algorithm.verify(JWT.decode(jwt)); }
@Test public void shouldThrowOnVerifyWhenTheSignatureIsNotPrepared() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg"); exception.expectCause(isA(SignatureException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(String.class), any(String.class), any(byte[].class))) .thenThrow(SignatureException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; algorithm.verify(JWT.decode(jwt)); }
@Test public void shouldThrowOnSignWhenThePrivateKeyIsInvalid() throws Exception { exception.expect(SignatureGenerationException.class); exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); exception.expectCause(isA(InvalidKeyException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class), any(byte[].class))) .thenThrow(InvalidKeyException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); algorithm.sign(ES256HeaderBytes, new byte[0]); }
@Test public void shouldThrowOnSignWhenTheSignatureIsNotPrepared() throws Exception { exception.expect(SignatureGenerationException.class); exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm"); exception.expectCause(isA(SignatureException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class), any(byte[].class))) .thenThrow(SignatureException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); algorithm.sign(ES256HeaderBytes, new byte[0]); }
@Test public void shouldThrowOnVerifyWhenSignatureAlgorithmDoesNotExists() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg"); exception.expectCause(isA(NoSuchAlgorithmException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(String.class), any(String.class), any(byte[].class))) .thenThrow(NoSuchAlgorithmException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; algorithm.verify(JWT.decode(jwt)); }
@Test public void shouldThrowOnVerifyWhenThePublicKeyIsInvalid() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg"); exception.expectCause(isA(InvalidKeyException.class)); CryptoHelper crypto = mock(CryptoHelper.class); when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(String.class), any(String.class), any(byte[].class))) .thenThrow(InvalidKeyException.class); ECPublicKey publicKey = mock(ECPublicKey.class); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider); String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g"; algorithm.verify(JWT.decode(jwt)); }
@Test public void shouldFailJOSEToDERConversionOnInvalidJOSESignatureLength() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); exception.expectCause(isA(SignatureException.class)); exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); byte[] bytes = new byte[256]; new SecureRandom().nextBytes(bytes); String signature = Base64.encodeBase64URLSafeString(bytes); String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; ECPublicKey publicKey = (ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm("ES256", "SHA256withECDSA", 128, provider); algorithm.verify(JWT.decode(jwt)); }
@Test public void shouldFailJOSEToDERConversionOnInvalidJOSESignatureLength() throws Exception { exception.expect(SignatureVerificationException.class); exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA"); exception.expectCause(isA(SignatureException.class)); exception.expectCause(hasMessage(is("Invalid JOSE signature format."))); byte[] bytes = new byte[256]; new SecureRandom().nextBytes(bytes); String signature = Base64.encodeBase64URLSafeString(bytes); String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature; ECPublicKey publicKey = (ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"); ECPrivateKey privateKey = mock(ECPrivateKey.class); ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey); Algorithm algorithm = new ECDSAAlgorithm("ES256", "SHA256withECDSA", 128, provider); algorithm.verify(JWT.decode(jwt)); }