Skip to content

Commit 4965a95

Browse files
committed
feat: load EC public key with given x, y and curve name
1 parent 7dfd02f commit 4965a95

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

key-pair-loader/src/main/java/com/onixbyte/security/KeyLoader.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.security.KeyFactory;
2323
import java.security.PrivateKey;
2424
import java.security.PublicKey;
25+
import java.security.interfaces.ECPublicKey;
2526
import java.security.interfaces.RSAPublicKey;
2627
import java.security.spec.KeySpec;
2728

@@ -67,6 +68,10 @@ default RSAPublicKey loadPublicKey(String modulus, String exponent) {
6768
throw new KeyLoadingException("This key loader does not support loading an RSA public key.");
6869
}
6970

71+
default ECPublicKey loadPublicKey(String xHex, String yHex, String curveName) {
72+
throw new KeyLoadingException("This key loader does not support loading an EC public key.");
73+
}
74+
7075
/**
7176
* Retrieves the raw content of a PEM formatted key by removing unnecessary headers, footers,
7277
* and new line characters.

key-pair-loader/src/main/java/com/onixbyte/security/impl/ECKeyLoader.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@
2020
import com.onixbyte.security.KeyLoader;
2121
import com.onixbyte.security.exception.KeyLoadingException;
2222

23+
import java.math.BigInteger;
24+
import java.security.AlgorithmParameters;
2325
import java.security.KeyFactory;
2426
import java.security.NoSuchAlgorithmException;
2527
import java.security.interfaces.ECPrivateKey;
2628
import java.security.interfaces.ECPublicKey;
27-
import java.security.spec.InvalidKeySpecException;
28-
import java.security.spec.PKCS8EncodedKeySpec;
29-
import java.security.spec.X509EncodedKeySpec;
29+
import java.security.spec.*;
3030
import java.util.Base64;
31+
import java.util.HashSet;
32+
import java.util.Set;
3133

3234
/**
3335
* Key pair loader for loading key pairs for ECDSA-based algorithms.
@@ -59,6 +61,13 @@ public class ECKeyLoader implements KeyLoader {
5961

6062
private final Base64.Decoder decoder;
6163

64+
/**
65+
* Supported curves.
66+
*/
67+
public static final Set<String> SUPPORTED_CURVES = new HashSet<>(Set.of(
68+
"secp256r1", "secp384r1", "secp521r1", "secp224r1"
69+
));
70+
6271
/**
6372
* Initialise a key loader for EC-based algorithms.
6473
*/
@@ -122,4 +131,38 @@ public ECPublicKey loadPublicKey(String pemKeyText) {
122131
}
123132
}
124133

134+
@Override
135+
public ECPublicKey loadPublicKey(String xHex, String yHex, String curveName) {
136+
if (!SUPPORTED_CURVES.contains(curveName)) {
137+
throw new KeyLoadingException("Given curve is not supported yet.");
138+
}
139+
140+
try {
141+
// Convert hex string coordinates to BigInteger
142+
var x = new BigInteger(xHex, 16);
143+
var y = new BigInteger(yHex, 16);
144+
145+
// Create ECPoint with (x, y)
146+
var ecPoint = new ECPoint(x, y);
147+
148+
// Get EC parameter spec for the named curve
149+
var parameters = AlgorithmParameters.getInstance("EC");
150+
parameters.init(new ECGenParameterSpec(curveName));
151+
var ecParameterSpec = parameters.getParameterSpec(ECParameterSpec.class);
152+
153+
// Create ECPublicKeySpec with point and curve params
154+
var pubSpec = new ECPublicKeySpec(ecPoint, ecParameterSpec);
155+
156+
// Generate public key using KeyFactory
157+
var publicKey = keyFactory.generatePublic(pubSpec);
158+
159+
if (publicKey instanceof ECPublicKey ecPublicKey) {
160+
return ecPublicKey;
161+
} else {
162+
throw new KeyLoadingException("Cannot load EC public key with given x, y and curve name.");
163+
}
164+
} catch (NoSuchAlgorithmException | InvalidParameterSpecException | InvalidKeySpecException e) {
165+
throw new KeyLoadingException("Cannot load EC public key with given x, y and curve name.", e);
166+
}
167+
}
125168
}

0 commit comments

Comments
 (0)