Skip to content

Commit ed2cf92

Browse files
Merge pull request #18919 from hmdrzsharifi/BAEL-6958
BAEL-6958: Key Encapsulation Mechanism API in Java
2 parents c08f208 + f844f47 commit ed2cf92

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

core-java-modules/core-java-security-5/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
</environmentVariables>
3131
</configuration>
3232
</plugin>
33+
<plugin>
34+
<groupId>org.apache.maven.plugins</groupId>
35+
<artifactId>maven-compiler-plugin</artifactId>
36+
<configuration>
37+
<source>21</source>
38+
<target>21</target>
39+
</configuration>
40+
</plugin>
3341
</plugins>
3442
</build>
3543

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.baeldung.kem;
2+
3+
import java.security.PrivateKey;
4+
import java.security.PublicKey;
5+
6+
import javax.crypto.KEM;
7+
import javax.crypto.SecretKey;
8+
9+
public class KemUtils {
10+
11+
public record KemResult(SecretKey sharedSecret, byte[] encapsulation) {}
12+
13+
public static KemResult encapsulate(String algorithm, PublicKey publicKey) throws Exception {
14+
KEM kem = KEM.getInstance(algorithm);
15+
KEM.Encapsulator encapsulator = kem.newEncapsulator(publicKey);
16+
KEM.Encapsulated result = encapsulator.encapsulate();
17+
return new KemResult(result.key(), result.encapsulation());
18+
}
19+
20+
public static KemResult decapsulate(String algorithm, PrivateKey privateKey, byte[] encapsulation)
21+
throws Exception {
22+
KEM kem = KEM.getInstance(algorithm);
23+
KEM.Decapsulator decapsulator = kem.newDecapsulator(privateKey);
24+
SecretKey recoveredSecret = decapsulator.decapsulate(encapsulation);
25+
return new KemResult(recoveredSecret, encapsulation);
26+
}
27+
28+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.baeldung.kem;
2+
3+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
import java.security.KeyPair;
8+
import java.security.KeyPairGenerator;
9+
10+
import javax.crypto.SecretKey;
11+
12+
import org.junit.jupiter.api.BeforeAll;
13+
import org.junit.jupiter.api.Test;
14+
15+
public class KemUtilsUnitTest {
16+
private static KeyPair keyPair;
17+
public static final String KEM_ALGORITHM = "DHKEM";
18+
19+
20+
@BeforeAll
21+
static void setup() throws Exception {
22+
KeyPairGenerator kpg = KeyPairGenerator.getInstance("X25519");
23+
keyPair = kpg.generateKeyPair();
24+
}
25+
26+
@Test
27+
void givenKem_whenSenderEncapsulatesAndReceiverDecapsulates_thenSecretsMatch() throws Exception {
28+
KemUtils.KemResult senderResult = KemUtils.encapsulate(KEM_ALGORITHM, keyPair.getPublic());
29+
assertNotNull(senderResult.sharedSecret());
30+
assertNotNull(senderResult.encapsulation());
31+
32+
KemUtils.KemResult receiverResult = KemUtils.decapsulate(KEM_ALGORITHM, keyPair.getPrivate(),
33+
senderResult.encapsulation());
34+
35+
SecretKey senderSecret = senderResult.sharedSecret();
36+
SecretKey receiverSecret = receiverResult.sharedSecret();
37+
38+
assertArrayEquals(senderSecret.getEncoded(), receiverSecret.getEncoded(),
39+
"Shared secrets from sender and receiver must match");
40+
}
41+
42+
@Test
43+
void givenDifferentReceiverKey_whenDecapsulate_thenFails() throws Exception {
44+
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
45+
KeyPair wrongKeyPair = kpg.generateKeyPair();
46+
47+
KemUtils.KemResult senderResult = KemUtils.encapsulate(KEM_ALGORITHM, keyPair.getPublic());
48+
49+
assertThrows(Exception.class, () ->
50+
KemUtils.decapsulate(KEM_ALGORITHM, wrongKeyPair.getPrivate(), senderResult.encapsulation()));
51+
}
52+
53+
}

0 commit comments

Comments
 (0)