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);