Skip to content

Commit 81f6acb

Browse files
author
Zihlu Wang
authored
Merge pull request #69 from onixbyte/release/2.3.0
2 parents 744f82f + d15adfd commit 81f6acb

File tree

12 files changed

+154
-347
lines changed

12 files changed

+154
-347
lines changed

gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
# limitations under the License.
1616
#
1717

18-
artefactVersion=2.2.0
19-
projectUrl=https://onixbyte.com/java-dev-kit
18+
artefactVersion=2.3.0
19+
projectUrl=https://onixbyte.com/projects/java-dev-kit
2020
projectGithubUrl=https://github.com/onixbyte/java-dev-kit
2121
licenseName=The Apache License, Version 2.0
22-
licenseUrl=https://www.apache.org/licenses/LICENSE-2.0.txt
22+
licenseUrl=https://onixbyte.com/projects/java-dev-kit/LICENSE.txt

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717

1818
package com.onixbyte.security;
1919

20+
import com.onixbyte.security.exception.KeyLoadingException;
21+
22+
import java.security.KeyFactory;
2023
import java.security.PrivateKey;
2124
import java.security.PublicKey;
25+
import java.security.interfaces.ECPublicKey;
26+
import java.security.interfaces.RSAPublicKey;
27+
import java.security.spec.KeySpec;
2228

2329
/**
2430
* The {@code KeyLoader} class provides utility methods for loading keys pairs from PEM-formatted
@@ -49,6 +55,41 @@ public interface KeyLoader {
4955
*/
5056
PublicKey loadPublicKey(String pemKeyText);
5157

58+
/**
59+
* Loads an RSA public key using the provided modulus and exponent.
60+
* <p>
61+
* This default implementation throws a {@link KeyLoadingException} to signify that this key loader does not support
62+
* loading an RSA public key. Implementing classes are expected to override this method to supply their own
63+
* loading logic.
64+
*
65+
* @param modulus the modulus value of the RSA public key, usually represented in hexadecimal or Base64
66+
* string format
67+
* @param exponent the public exponent value of the RSA public key, usually represented in hexadecimal or Base64
68+
* string format
69+
* @return the loaded {@link RSAPublicKey} instance
70+
* @throws KeyLoadingException if loading is not supported or fails
71+
*/
72+
default RSAPublicKey loadPublicKey(String modulus, String exponent) {
73+
throw new KeyLoadingException("This key loader does not support loading an RSA public key.");
74+
}
75+
76+
/**
77+
* Loads an EC public key using the provided x and y coordinates together with the curve name.
78+
* <p>
79+
* This default implementation throws a {@link KeyLoadingException} to signify that this key loader does not support
80+
* loading an EC public key. Implementing classes are expected to override this method to supply their own
81+
* loading logic.
82+
*
83+
* @param xHex the hexadecimal string representing the x coordinate of the EC point
84+
* @param yHex the hexadecimal string representing the y coordinate of the EC point
85+
* @param curveName the name of the elliptic curve
86+
* @return the loaded {@link ECPublicKey} instance
87+
* @throws KeyLoadingException if loading is not supported or fails
88+
*/
89+
default ECPublicKey loadPublicKey(String xHex, String yHex, String curveName) {
90+
throw new KeyLoadingException("This key loader does not support loading an EC public key.");
91+
}
92+
5293
/**
5394
* Retrieves the raw content of a PEM formatted key by removing unnecessary headers, footers,
5495
* and new line characters.

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

Lines changed: 65 additions & 5 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.
@@ -53,16 +55,23 @@
5355
* @version 2.0.0
5456
* @since 2.0.0
5557
*/
56-
public class EcKeyLoader implements KeyLoader {
58+
public class ECKeyLoader implements KeyLoader {
5759

5860
private final KeyFactory keyFactory;
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
*/
65-
public EcKeyLoader() {
74+
public ECKeyLoader() {
6675
try {
6776
this.keyFactory = KeyFactory.getInstance("EC");
6877
this.decoder = Base64.getDecoder();
@@ -122,4 +131,55 @@ public ECPublicKey loadPublicKey(String pemKeyText) {
122131
}
123132
}
124133

134+
/**
135+
* Loads an EC public key from the given hexadecimal x and y coordinates alongside the curve name.
136+
* <p>
137+
* This method converts the hexadecimal string representations of the EC point coordinates into {@link BigInteger}
138+
* instances, then constructs an {@link ECPoint} and retrieves the corresponding {@link ECParameterSpec} for the
139+
* named curve. Subsequently, it utilises the {@link KeyFactory} to generate an {@link ECPublicKey}.
140+
* <p>
141+
* Only curves listed in {@link #SUPPORTED_CURVES} are supported. Should the specified curve name be unsupported,
142+
* or if key construction fails due to invalid parameters or unsupported algorithms, a {@link KeyLoadingException}
143+
* will be thrown.
144+
*
145+
* @param xHex the hexadecimal string representing the x-coordinate of the EC point
146+
* @param yHex the hexadecimal string representing the y-coordinate of the EC point
147+
* @param curveName the name of the elliptic curve
148+
* @return the {@link ECPublicKey} generated from the specified coordinates and curve
149+
* @throws KeyLoadingException if the curve is unsupported or key generation fails
150+
*/
151+
@Override
152+
public ECPublicKey loadPublicKey(String xHex, String yHex, String curveName) {
153+
if (!SUPPORTED_CURVES.contains(curveName)) {
154+
throw new KeyLoadingException("Given curve is not supported yet.");
155+
}
156+
157+
try {
158+
// Convert hex string coordinates to BigInteger
159+
var x = new BigInteger(xHex, 16);
160+
var y = new BigInteger(yHex, 16);
161+
162+
// Create ECPoint with (x, y)
163+
var ecPoint = new ECPoint(x, y);
164+
165+
// Get EC parameter spec for the named curve
166+
var parameters = AlgorithmParameters.getInstance("EC");
167+
parameters.init(new ECGenParameterSpec(curveName));
168+
var ecParameterSpec = parameters.getParameterSpec(ECParameterSpec.class);
169+
170+
// Create ECPublicKeySpec with point and curve params
171+
var pubSpec = new ECPublicKeySpec(ecPoint, ecParameterSpec);
172+
173+
// Generate public key using KeyFactory
174+
var publicKey = keyFactory.generatePublic(pubSpec);
175+
176+
if (publicKey instanceof ECPublicKey ecPublicKey) {
177+
return ecPublicKey;
178+
} else {
179+
throw new KeyLoadingException("Cannot load EC public key with given x, y and curve name.");
180+
}
181+
} catch (NoSuchAlgorithmException | InvalidParameterSpecException | InvalidKeySpecException e) {
182+
throw new KeyLoadingException("Cannot load EC public key with given x, y and curve name.", e);
183+
}
184+
}
125185
}

key-pair-loader/src/main/java/com/onixbyte/security/impl/RsaKeyLoader.java renamed to key-pair-loader/src/main/java/com/onixbyte/security/impl/RSAKeyLoader.java

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,12 @@
2020
import com.onixbyte.security.KeyLoader;
2121
import com.onixbyte.security.exception.KeyLoadingException;
2222

23+
import java.math.BigInteger;
2324
import java.security.KeyFactory;
2425
import java.security.NoSuchAlgorithmException;
2526
import java.security.interfaces.RSAPrivateKey;
2627
import java.security.interfaces.RSAPublicKey;
27-
import java.security.spec.InvalidKeySpecException;
28-
import java.security.spec.PKCS8EncodedKeySpec;
29-
import java.security.spec.X509EncodedKeySpec;
28+
import java.security.spec.*;
3029
import java.util.Base64;
3130

3231
/**
@@ -44,9 +43,12 @@
4443
* @see KeyLoader
4544
* @see KeyLoadingException
4645
*/
47-
public class RsaKeyLoader implements KeyLoader {
46+
public class RSAKeyLoader implements KeyLoader {
4847

4948
private final Base64.Decoder decoder;
49+
50+
private final Base64.Decoder urlDecoder;
51+
5052
private final KeyFactory keyFactory;
5153

5254
/**
@@ -55,9 +57,10 @@ public class RsaKeyLoader implements KeyLoader {
5557
* This constructor initialises the Base64 decoder and the RSA {@link KeyFactory}. It may throw
5658
* a {@link KeyLoadingException} if the RSA algorithm is not available.
5759
*/
58-
public RsaKeyLoader() {
60+
public RSAKeyLoader() {
5961
try {
6062
this.decoder = Base64.getDecoder();
63+
this.urlDecoder = Base64.getUrlDecoder();
6164
this.keyFactory = KeyFactory.getInstance("RSA");
6265
} catch (NoSuchAlgorithmException e) {
6366
throw new KeyLoadingException(e);
@@ -133,4 +136,31 @@ public RSAPublicKey loadPublicKey(String pemKeyText) {
133136
throw new KeyLoadingException("Key spec is invalid.", e);
134137
}
135138
}
139+
140+
/**
141+
* Get the public key with given modulus and public exponent.
142+
*
143+
* @param modulus the modulus
144+
* @param exponent the public exponent
145+
* @return generated public key object from the provided key specification
146+
* @see KeyFactory#getInstance(String)
147+
* @see KeyFactory#generatePublic(KeySpec)
148+
*/
149+
@Override
150+
public RSAPublicKey loadPublicKey(String modulus, String exponent) {
151+
try {
152+
var _modulus = new BigInteger(1, urlDecoder.decode(modulus));
153+
var _exponent = new BigInteger(1, urlDecoder.decode(exponent));
154+
155+
var keySpec = new RSAPublicKeySpec(_modulus, _exponent);
156+
var kf = KeyFactory.getInstance("RSA");
157+
if (kf.generatePublic(keySpec) instanceof RSAPublicKey rsaPublicKey) {
158+
return rsaPublicKey;
159+
} else {
160+
throw new KeyLoadingException("Cannot generate RSA public key with given modulus and exponent.");
161+
}
162+
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
163+
throw new KeyLoadingException("Cannot generate RSA public key with given modulus and exponent.", e);
164+
}
165+
}
136166
}

map-util-unsafe/src/main/java/com/onixbyte/devkit/utils/unsafe/ReflectMapUtil.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,27 +33,27 @@
3333
* as maps for serialization, deserialization, or other purposes, and where the structure of the
3434
* objects is not known at compile time.
3535
* </p>
36-
*
36+
*
3737
* <p><b>Example usage:</b></p>
3838
* <pre>
3939
* {@code
4040
* public class User {
4141
* private String name;
4242
* private int age;
43-
*
43+
*
4444
* // getters and setters
4545
* }
46-
*
46+
*
4747
* public class Example {
4848
* public static void main(String[] args) throws IllegalAccessException {
4949
* User user = new User();
5050
* user.setName("John");
5151
* user.setAge(30);
52-
*
52+
*
5353
* // Convert object to map
5454
* Map<String, Object> userMap = ReflectMapUtil.objectToMap(user);
5555
* System.out.println(userMap); // Output: {name=John, age=30}
56-
*
56+
*
5757
* // Convert map to object
5858
* User newUser = ReflectMapUtil.mapToObject(userMap, User.class);
5959
* System.out.println(newUser.getName()); // Output: John
@@ -66,7 +66,10 @@
6666
* @author zihluwang
6767
* @version 1.4.2
6868
* @since 1.4.2
69+
* @deprecated This utility class is no longer maintained and will be removed in a future release. If you still need to
70+
* use {@link ReflectMapUtil}, please stick to the last available version (2.2.0).
6971
*/
72+
@Deprecated(forRemoval = true, since = "2.2.0")
7073
public final class ReflectMapUtil {
7174

7275
private final static Logger log = LoggerFactory.getLogger(ReflectMapUtil.class);

property-guard-spring-boot-starter/README.md

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)