diff --git a/core-java-modules/core-java-security-5/pom.xml b/core-java-modules/core-java-security-5/pom.xml index 6a435207e6fb..9053a1b0f021 100644 --- a/core-java-modules/core-java-security-5/pom.xml +++ b/core-java-modules/core-java-security-5/pom.xml @@ -30,6 +30,14 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + 21 + 21 + + diff --git a/core-java-modules/core-java-security-5/src/main/java/com/baeldung/kem/KemUtils.java b/core-java-modules/core-java-security-5/src/main/java/com/baeldung/kem/KemUtils.java new file mode 100644 index 000000000000..2d8bbc19998b --- /dev/null +++ b/core-java-modules/core-java-security-5/src/main/java/com/baeldung/kem/KemUtils.java @@ -0,0 +1,28 @@ +package com.baeldung.kem; + +import java.security.PrivateKey; +import java.security.PublicKey; + +import javax.crypto.KEM; +import javax.crypto.SecretKey; + +public class KemUtils { + + public record KemResult(SecretKey sharedSecret, byte[] encapsulation) {} + + public static KemResult encapsulate(String algorithm, PublicKey publicKey) throws Exception { + KEM kem = KEM.getInstance(algorithm); + KEM.Encapsulator encapsulator = kem.newEncapsulator(publicKey); + KEM.Encapsulated result = encapsulator.encapsulate(); + return new KemResult(result.key(), result.encapsulation()); + } + + public static KemResult decapsulate(String algorithm, PrivateKey privateKey, byte[] encapsulation) + throws Exception { + KEM kem = KEM.getInstance(algorithm); + KEM.Decapsulator decapsulator = kem.newDecapsulator(privateKey); + SecretKey recoveredSecret = decapsulator.decapsulate(encapsulation); + return new KemResult(recoveredSecret, encapsulation); + } + +} diff --git a/core-java-modules/core-java-security-5/src/test/java/com/baeldung/kem/KemUtilsUnitTest.java b/core-java-modules/core-java-security-5/src/test/java/com/baeldung/kem/KemUtilsUnitTest.java new file mode 100644 index 000000000000..08c5c06ddcaf --- /dev/null +++ b/core-java-modules/core-java-security-5/src/test/java/com/baeldung/kem/KemUtilsUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.kem; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; + +import javax.crypto.SecretKey; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class KemUtilsUnitTest { + private static KeyPair keyPair; + public static final String KEM_ALGORITHM = "DHKEM"; + + + @BeforeAll + static void setup() throws Exception { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("X25519"); + keyPair = kpg.generateKeyPair(); + } + + @Test + void givenKem_whenSenderEncapsulatesAndReceiverDecapsulates_thenSecretsMatch() throws Exception { + KemUtils.KemResult senderResult = KemUtils.encapsulate(KEM_ALGORITHM, keyPair.getPublic()); + assertNotNull(senderResult.sharedSecret()); + assertNotNull(senderResult.encapsulation()); + + KemUtils.KemResult receiverResult = KemUtils.decapsulate(KEM_ALGORITHM, keyPair.getPrivate(), + senderResult.encapsulation()); + + SecretKey senderSecret = senderResult.sharedSecret(); + SecretKey receiverSecret = receiverResult.sharedSecret(); + + assertArrayEquals(senderSecret.getEncoded(), receiverSecret.getEncoded(), + "Shared secrets from sender and receiver must match"); + } + + @Test + void givenDifferentReceiverKey_whenDecapsulate_thenFails() throws Exception { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); + KeyPair wrongKeyPair = kpg.generateKeyPair(); + + KemUtils.KemResult senderResult = KemUtils.encapsulate(KEM_ALGORITHM, keyPair.getPublic()); + + assertThrows(Exception.class, () -> + KemUtils.decapsulate(KEM_ALGORITHM, wrongKeyPair.getPrivate(), senderResult.encapsulation())); + } + +}