diff --git a/Dockerfile b/Dockerfile index b9e031d64..7c0aa5087 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ # sha from https://hub.docker.com/layers/library/eclipse-temurin/21.0.9_10-jre-alpine-3.23/images/sha256-f599f6fa11f007b6dcf6e85ec2c372c1eba2b6940a7828eb6e665665ea5edd1c FROM eclipse-temurin@sha256:243e711289b0f17e05a4df60454bbb1b8ed7b126db4de2d5535da994b7417111 +RUN apk add --no-cache gcompat + WORKDIR /app EXPOSE 8080 diff --git a/pom.xml b/pom.xml index 77d3f95a0..ac7a35383 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,7 @@ com.uid2.operator.vertx.UIDOperatorVerticle 1.12.2 + 2.5.0 2.1.6 2.1.0 2.1.19 @@ -203,6 +204,26 @@ 5.12.0 test + + + + software.amazon.cryptools + AmazonCorrettoCryptoProvider + ${accp.version} + linux-x86_64 + + + software.amazon.cryptools + AmazonCorrettoCryptoProvider + ${accp.version} + osx-x86_64 + + + software.amazon.cryptools + AmazonCorrettoCryptoProvider + ${accp.version} + osx-aarch_64 + diff --git a/src/main/java/com/uid2/operator/service/CryptoProviderService.java b/src/main/java/com/uid2/operator/service/CryptoProviderService.java new file mode 100644 index 000000000..c9fee2df3 --- /dev/null +++ b/src/main/java/com/uid2/operator/service/CryptoProviderService.java @@ -0,0 +1,53 @@ +package com.uid2.operator.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.amazon.corretto.crypto.provider.AmazonCorrettoCryptoProvider; + +import javax.crypto.KeyAgreement; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Security; + +public class CryptoProviderService { + private static final Logger LOGGER = LoggerFactory.getLogger(CryptoProviderService.class); + + // ECDH provider selection: tries ACCP first, falls back to default (SunEC) + private static final String ECDH_PROVIDER_NAME = initEcdhProvider(); + + private static String initEcdhProvider() { + // Try ACCP (Amazon Corretto Crypto Provider) first + try { + // Add ACCP at lowest priority so it doesn't become default for other algorithms + Security.addProvider(AmazonCorrettoCryptoProvider.INSTANCE); + + // Verify it works for ECDH + KeyAgreement ka = KeyAgreement.getInstance("ECDH", AmazonCorrettoCryptoProvider.PROVIDER_NAME); + LOGGER.info("ECDH using AmazonCorrettoCryptoProvider (added at lowest priority)"); + return AmazonCorrettoCryptoProvider.PROVIDER_NAME; + } catch (Throwable e) { + // ACCP not available + LOGGER.info("AmazonCorrettoCryptoProvider is not available: {}", e.getMessage()); + } + + // Fall back to default provider + LOGGER.info("ECDH using default provider (SunEC)"); + return null; + } + + /** + * Create ECDH Key Agreement using ACCP if available, fall back to SunEC if not + * @return ECDH KeyAgreement + * @throws NoSuchAlgorithmException + */ + public static KeyAgreement createKeyAgreement() throws NoSuchAlgorithmException { + if (ECDH_PROVIDER_NAME != null) { + try { + return KeyAgreement.getInstance("ECDH", ECDH_PROVIDER_NAME); + } catch (NoSuchProviderException e) { + LOGGER.info("{} is not available: {}", ECDH_PROVIDER_NAME, e.getMessage()); + } + } + return KeyAgreement.getInstance("ECDH"); + } +} diff --git a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java index fd11f4882..7b36e8eea 100644 --- a/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java +++ b/src/main/java/com/uid2/operator/vertx/UIDOperatorVerticle.java @@ -409,7 +409,7 @@ private void handleClientSideTokenGenerateImpl(RoutingContext rc) throws NoSuchA } // Perform key agreement - final KeyAgreement ka = KeyAgreement.getInstance("ECDH"); + final KeyAgreement ka = CryptoProviderService.createKeyAgreement(); ka.init(clientSideKeypair.getPrivateKey()); ka.doPhase(clientPublicKey, true); diff --git a/src/test/java/com/uid2/operator/ClientSideTokenGenerateTestUtil.java b/src/test/java/com/uid2/operator/ClientSideTokenGenerateTestUtil.java index 22029a0ff..22219ae23 100644 --- a/src/test/java/com/uid2/operator/ClientSideTokenGenerateTestUtil.java +++ b/src/test/java/com/uid2/operator/ClientSideTokenGenerateTestUtil.java @@ -1,5 +1,7 @@ package com.uid2.operator; +import com.uid2.operator.service.CryptoProviderService; + import javax.crypto.*; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -37,7 +39,7 @@ public static PrivateKey stringToPrivateKey(String privateKeyString, KeyFactory } public static SecretKey deriveKey(PublicKey serverPublicKey, PrivateKey clientPrivateKey) throws NoSuchAlgorithmException, InvalidKeyException { - KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH"); + KeyAgreement keyAgreement = CryptoProviderService.createKeyAgreement(); keyAgreement.init(clientPrivateKey); keyAgreement.doPhase(serverPublicKey, true);