feat: load EC public key with given x, y and curve name

This commit is contained in:
siujamo
2025-06-09 12:40:29 +08:00
parent 7dfd02f11e
commit 4965a95297
2 changed files with 51 additions and 3 deletions
@@ -22,6 +22,7 @@ import com.onixbyte.security.exception.KeyLoadingException;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPublicKey;
import java.security.spec.KeySpec; import java.security.spec.KeySpec;
@@ -67,6 +68,10 @@ public interface KeyLoader {
throw new KeyLoadingException("This key loader does not support loading an RSA public key."); throw new KeyLoadingException("This key loader does not support loading an RSA public key.");
} }
default ECPublicKey loadPublicKey(String xHex, String yHex, String curveName) {
throw new KeyLoadingException("This key loader does not support loading an EC public key.");
}
/** /**
* Retrieves the raw content of a PEM formatted key by removing unnecessary headers, footers, * Retrieves the raw content of a PEM formatted key by removing unnecessary headers, footers,
* and new line characters. * and new line characters.
@@ -20,14 +20,16 @@ package com.onixbyte.security.impl;
import com.onixbyte.security.KeyLoader; import com.onixbyte.security.KeyLoader;
import com.onixbyte.security.exception.KeyLoadingException; import com.onixbyte.security.exception.KeyLoadingException;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64; import java.util.Base64;
import java.util.HashSet;
import java.util.Set;
/** /**
* Key pair loader for loading key pairs for ECDSA-based algorithms. * Key pair loader for loading key pairs for ECDSA-based algorithms.
@@ -59,6 +61,13 @@ public class ECKeyLoader implements KeyLoader {
private final Base64.Decoder decoder; private final Base64.Decoder decoder;
/**
* Supported curves.
*/
public static final Set<String> SUPPORTED_CURVES = new HashSet<>(Set.of(
"secp256r1", "secp384r1", "secp521r1", "secp224r1"
));
/** /**
* Initialise a key loader for EC-based algorithms. * Initialise a key loader for EC-based algorithms.
*/ */
@@ -122,4 +131,38 @@ public class ECKeyLoader implements KeyLoader {
} }
} }
@Override
public ECPublicKey loadPublicKey(String xHex, String yHex, String curveName) {
if (!SUPPORTED_CURVES.contains(curveName)) {
throw new KeyLoadingException("Given curve is not supported yet.");
}
try {
// Convert hex string coordinates to BigInteger
var x = new BigInteger(xHex, 16);
var y = new BigInteger(yHex, 16);
// Create ECPoint with (x, y)
var ecPoint = new ECPoint(x, y);
// Get EC parameter spec for the named curve
var parameters = AlgorithmParameters.getInstance("EC");
parameters.init(new ECGenParameterSpec(curveName));
var ecParameterSpec = parameters.getParameterSpec(ECParameterSpec.class);
// Create ECPublicKeySpec with point and curve params
var pubSpec = new ECPublicKeySpec(ecPoint, ecParameterSpec);
// Generate public key using KeyFactory
var publicKey = keyFactory.generatePublic(pubSpec);
if (publicKey instanceof ECPublicKey ecPublicKey) {
return ecPublicKey;
} else {
throw new KeyLoadingException("Cannot load EC public key with given x, y and curve name.");
}
} catch (NoSuchAlgorithmException | InvalidParameterSpecException | InvalidKeySpecException e) {
throw new KeyLoadingException("Cannot load EC public key with given x, y and curve name.", e);
}
}
} }