|
20 | 20 | import com.onixbyte.security.KeyLoader; |
21 | 21 | import com.onixbyte.security.exception.KeyLoadingException; |
22 | 22 |
|
| 23 | +import java.math.BigInteger; |
| 24 | +import java.security.AlgorithmParameters; |
23 | 25 | import java.security.KeyFactory; |
24 | 26 | import java.security.NoSuchAlgorithmException; |
25 | 27 | import java.security.interfaces.ECPrivateKey; |
26 | 28 | 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.*; |
30 | 30 | import java.util.Base64; |
| 31 | +import java.util.HashSet; |
| 32 | +import java.util.Set; |
31 | 33 |
|
32 | 34 | /** |
33 | 35 | * Key pair loader for loading key pairs for ECDSA-based algorithms. |
@@ -59,6 +61,13 @@ public class ECKeyLoader implements KeyLoader { |
59 | 61 |
|
60 | 62 | private final Base64.Decoder decoder; |
61 | 63 |
|
| 64 | + /** |
| 65 | + * Supported curves. |
| 66 | + */ |
| 67 | + public static final Set<String> SUPPORTED_CURVES = new HashSet<>(Set.of( |
| 68 | + "secp256r1", "secp384r1", "secp521r1", "secp224r1" |
| 69 | + )); |
| 70 | + |
62 | 71 | /** |
63 | 72 | * Initialise a key loader for EC-based algorithms. |
64 | 73 | */ |
@@ -122,4 +131,38 @@ public ECPublicKey loadPublicKey(String pemKeyText) { |
122 | 131 | } |
123 | 132 | } |
124 | 133 |
|
| 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 | + } |
125 | 168 | } |
0 commit comments