79 files changed
+501
-336
No files matched your search
File renamed without changes.
@@ -64,14 +64,14 @@ tasks.test {
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("devkitUtils") {
|
||||
create<MavenPublication>("commonToolbox") {
|
||||
groupId = group.toString()
|
||||
artifactId = "devkit-utils"
|
||||
artifactId = "common-toolbox"
|
||||
version = artefactVersion
|
||||
|
||||
pom {
|
||||
name = "OnixByte Common Toolbox"
|
||||
description = "The utils module of JDevKit."
|
||||
description = "The utils module of OnixByte toolbox."
|
||||
url = projectUrl
|
||||
|
||||
licenses {
|
||||
@@ -82,8 +82,8 @@ publishing {
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
connection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
url = projectGithubUrl
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ publishing {
|
||||
from(components["java"])
|
||||
|
||||
signing {
|
||||
sign(publishing.publications["devkitUtils"])
|
||||
sign(publishing.publications["commonToolbox"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,4 +122,4 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+3
@@ -17,7 +17,10 @@
|
||||
|
||||
package com.onixbyte.devkit.utils;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -68,9 +68,9 @@ tasks.test {
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("keyPairLoader") {
|
||||
create<MavenPublication>("cryptoToolbox") {
|
||||
groupId = group.toString()
|
||||
artifactId = "key-pair-loader"
|
||||
artifactId = "crypto-toolbox"
|
||||
version = artefactVersion
|
||||
|
||||
pom {
|
||||
@@ -87,8 +87,8 @@ publishing {
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
connection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
url = projectGithubUrl
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ publishing {
|
||||
from(components["java"])
|
||||
|
||||
signing {
|
||||
sign(publishing.publications["keyPairLoader"])
|
||||
sign(publishing.publications["cryptoToolbox"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,4 +127,4 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.crypto;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
|
||||
/**
|
||||
* The {@code PrivateKeyLoader} interface provides utility methods for loading keys pairs from
|
||||
* PEM-formatted key text. This class supports loading both private and public keys.
|
||||
*
|
||||
* @author zihluwang
|
||||
* @author siujamo
|
||||
* @version 2.0.0
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public interface PrivateKeyLoader {
|
||||
|
||||
/**
|
||||
* Load private key from pem-formatted key text.
|
||||
*
|
||||
* @param pemKeyText pem-formatted key text
|
||||
* @return loaded private key
|
||||
*/
|
||||
PrivateKey loadPrivateKey(String pemKeyText);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.crypto;
|
||||
|
||||
import com.onixbyte.crypto.exception.KeyLoadingException;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author siujamo
|
||||
* @version 3.0.0
|
||||
*/
|
||||
public interface PublicKeyLoader {
|
||||
|
||||
/**
|
||||
* Load public key from pem-formatted key text.
|
||||
*
|
||||
* @param pemKeyText pem-formatted key text
|
||||
* @return loaded private key
|
||||
*/
|
||||
PublicKey loadPublicKey(String pemKeyText);
|
||||
|
||||
/**
|
||||
* Loads an EC public key using the provided x and y coordinates together with the curve name.
|
||||
* <p>
|
||||
* This default implementation throws a {@link KeyLoadingException} to signify that this key
|
||||
* loader does not support loading an EC public key. Implementing classes are expected to
|
||||
* override this method to supply their own loading logic.
|
||||
*
|
||||
* @param xHex the hexadecimal string representing the x coordinate of the EC point
|
||||
* @param yHex the hexadecimal string representing the y coordinate of the EC point
|
||||
* @param curveName the name of the elliptic curve
|
||||
* @return the loaded {@link ECPublicKey} instance
|
||||
* @throws KeyLoadingException if loading is not supported or fails
|
||||
*/
|
||||
default ECPublicKey loadPublicKey(String xHex, String yHex, String curveName) {
|
||||
throw new KeyLoadingException("This key loader does not support loading an EC public key.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an RSA public key using the provided modulus and exponent.
|
||||
* <p>
|
||||
* This default implementation throws a {@link KeyLoadingException} to signify that this key
|
||||
* loader does not support loading an RSA public key. Implementing classes are expected to
|
||||
* override this method to supply their own loading logic.
|
||||
*
|
||||
* @param modulus the modulus value of the RSA public key, usually represented in hexadecimal
|
||||
* or Base64 string format
|
||||
* @param exponent the public exponent value of the RSA public key, usually represented in
|
||||
* hexadecimal or Base64 string format
|
||||
* @return the loaded {@link RSAPublicKey} instance
|
||||
* @throws KeyLoadingException if loading is not supported or fails
|
||||
*/
|
||||
default RSAPublicKey loadPublicKey(String modulus, String exponent) {
|
||||
throw new KeyLoadingException("This key loader does not support loading an RSA public key.");
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.crypto.algorithm.ecdsa;
|
||||
|
||||
import com.onixbyte.crypto.PrivateKeyLoader;
|
||||
import com.onixbyte.crypto.exception.KeyLoadingException;
|
||||
import com.onixbyte.crypto.util.CryptoUtil;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.spec.*;
|
||||
import java.util.Base64;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Key pair loader for loading key pairs for ECDSA-based algorithms.
|
||||
* <p>
|
||||
*
|
||||
* <b>Example usage for ECDSA:</b>
|
||||
* <pre>{@code
|
||||
* PrivateKeyLoader keyLoader = new EcKeyLoader();
|
||||
* String pemPrivateKey = """
|
||||
* -----BEGIN EC PRIVATE KEY-----
|
||||
* ...
|
||||
* -----END EC PRIVATE KEY-----""";
|
||||
* ECPrivateKey privateKey = PrivateKeyLoader.loadEcdsaPrivateKey(pemPrivateKey);
|
||||
*
|
||||
* String pemPublicKey = """
|
||||
* -----BEGIN EC PUBLIC KEY-----
|
||||
* ...
|
||||
* -----END EC PUBLIC KEY-----""";
|
||||
* ECPublicKey publicKey = PrivateKeyLoader.loadPublicKey(pemPublicKey);
|
||||
* }</pre>
|
||||
*
|
||||
* @author zihluwang
|
||||
* @version 2.0.0
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class ECPrivateKeyLoader implements PrivateKeyLoader {
|
||||
|
||||
private final KeyFactory keyFactory;
|
||||
|
||||
private final Base64.Decoder decoder;
|
||||
|
||||
/**
|
||||
* Initialise a key loader for EC-based algorithms.
|
||||
*/
|
||||
public ECPrivateKeyLoader() {
|
||||
try {
|
||||
this.keyFactory = KeyFactory.getInstance("EC");
|
||||
this.decoder = Base64.getDecoder();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new KeyLoadingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load ECDSA private key from pem-formatted key text.
|
||||
*
|
||||
* @param pemKeyText pem-formatted key text
|
||||
* @return loaded private key
|
||||
* @throws KeyLoadingException if the generated key is not a {@link ECPrivateKey} instance,
|
||||
* or EC Key Factory is not loaded, or key spec is invalid
|
||||
*/
|
||||
@Override
|
||||
public ECPrivateKey loadPrivateKey(String pemKeyText) {
|
||||
try {
|
||||
pemKeyText = CryptoUtil.getRawContent(pemKeyText);
|
||||
var decodedKeyString = decoder.decode(pemKeyText);
|
||||
var keySpec = new PKCS8EncodedKeySpec(decodedKeyString);
|
||||
|
||||
var _key = keyFactory.generatePrivate(keySpec);
|
||||
if (_key instanceof ECPrivateKey privateKey) {
|
||||
return privateKey;
|
||||
} else {
|
||||
throw new KeyLoadingException("Unable to load private key from pem-formatted key text.");
|
||||
}
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new KeyLoadingException("Key spec is invalid.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
-63
@@ -15,10 +15,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.security.impl;
|
||||
package com.onixbyte.crypto.algorithm.ecdsa;
|
||||
|
||||
import com.onixbyte.security.KeyLoader;
|
||||
import com.onixbyte.security.exception.KeyLoadingException;
|
||||
import com.onixbyte.crypto.PublicKeyLoader;
|
||||
import com.onixbyte.crypto.exception.KeyLoadingException;
|
||||
import com.onixbyte.crypto.util.CryptoUtil;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameters;
|
||||
@@ -31,47 +32,23 @@ import java.util.Base64;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Key pair loader for loading key pairs for ECDSA-based algorithms.
|
||||
* <p>
|
||||
*
|
||||
* <b>Example usage for ECDSA:</b>
|
||||
* <pre>{@code
|
||||
* KeyLoader keyLoader = new EcKeyLoader();
|
||||
* String pemPrivateKey = """
|
||||
* -----BEGIN EC PRIVATE KEY-----
|
||||
* ...
|
||||
* -----END EC PRIVATE KEY-----""";
|
||||
* ECPrivateKey privateKey = KeyLoader.loadEcdsaPrivateKey(pemPrivateKey);
|
||||
*
|
||||
* String pemPublicKey = """
|
||||
* -----BEGIN EC PUBLIC KEY-----
|
||||
* ...
|
||||
* -----END EC PUBLIC KEY-----""";
|
||||
* ECPublicKey publicKey = KeyLoader.loadPublicKey(pemPublicKey);
|
||||
* }</pre>
|
||||
*
|
||||
* @author zihluwang
|
||||
* @version 2.0.0
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class ECKeyLoader implements KeyLoader {
|
||||
public class ECPublicKeyLoader implements PublicKeyLoader {
|
||||
|
||||
/**
|
||||
* Supported curves.
|
||||
*/
|
||||
public static final Set<String> SUPPORTED_CURVES = new HashSet<>(Set.of(
|
||||
"secp256r1", "secp384r1", "secp521r1", "secp224r1"
|
||||
));
|
||||
|
||||
private final KeyFactory keyFactory;
|
||||
|
||||
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.
|
||||
*/
|
||||
public ECKeyLoader() {
|
||||
public ECPublicKeyLoader() {
|
||||
try {
|
||||
this.keyFactory = KeyFactory.getInstance("EC");
|
||||
this.decoder = Base64.getDecoder();
|
||||
@@ -80,32 +57,6 @@ public class ECKeyLoader implements KeyLoader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load ECDSA private key from pem-formatted key text.
|
||||
*
|
||||
* @param pemKeyText pem-formatted key text
|
||||
* @return loaded private key
|
||||
* @throws KeyLoadingException if the generated key is not a {@link ECPrivateKey} instance,
|
||||
* or EC Key Factory is not loaded, or key spec is invalid
|
||||
*/
|
||||
@Override
|
||||
public ECPrivateKey loadPrivateKey(String pemKeyText) {
|
||||
try {
|
||||
pemKeyText = getRawContent(pemKeyText);
|
||||
var decodedKeyString = decoder.decode(pemKeyText);
|
||||
var keySpec = new PKCS8EncodedKeySpec(decodedKeyString);
|
||||
|
||||
var _key = keyFactory.generatePrivate(keySpec);
|
||||
if (_key instanceof ECPrivateKey privateKey) {
|
||||
return privateKey;
|
||||
} else {
|
||||
throw new KeyLoadingException("Unable to load private key from pem-formatted key text.");
|
||||
}
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new KeyLoadingException("Key spec is invalid.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load public key from pem-formatted key text.
|
||||
*
|
||||
@@ -117,7 +68,7 @@ public class ECKeyLoader implements KeyLoader {
|
||||
@Override
|
||||
public ECPublicKey loadPublicKey(String pemKeyText) {
|
||||
try {
|
||||
pemKeyText = getRawContent(pemKeyText);
|
||||
pemKeyText = CryptoUtil.getRawContent(pemKeyText);
|
||||
var keyBytes = decoder.decode(pemKeyText);
|
||||
var spec = new X509EncodedKeySpec(keyBytes);
|
||||
var key = keyFactory.generatePublic(spec);
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.crypto.algorithm.rsa;
|
||||
|
||||
import com.onixbyte.crypto.PrivateKeyLoader;
|
||||
import com.onixbyte.crypto.exception.KeyLoadingException;
|
||||
import com.onixbyte.crypto.util.CryptoUtil;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.*;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* A class responsible for loading RSA keys from PEM formatted text.
|
||||
* <p>
|
||||
* This class implements the {@link PrivateKeyLoader} interface and provides methods to load both private
|
||||
* and public RSA keys. The keys are expected to be in the standard PEM format, which includes
|
||||
* Base64-encoded key content surrounded by header and footer lines. The class handles the decoding
|
||||
* of Base64 content and the generation of keys using the RSA key factory.
|
||||
* <p>
|
||||
* Any exceptions encountered during the loading process are encapsulated in a
|
||||
* {@link KeyLoadingException}, allowing for flexible error handling.
|
||||
*
|
||||
* @author siujamo
|
||||
* @see PrivateKeyLoader
|
||||
* @see KeyLoadingException
|
||||
*/
|
||||
public class RSAPrivateKeyLoader implements PrivateKeyLoader {
|
||||
|
||||
private final Base64.Decoder decoder;
|
||||
|
||||
private final KeyFactory keyFactory;
|
||||
|
||||
/**
|
||||
* Constructs an instance of {@code RsaKeyLoader}.
|
||||
* <p>
|
||||
* This constructor initialises the Base64 decoder and the RSA {@link KeyFactory}. It may throw
|
||||
* a {@link KeyLoadingException} if the RSA algorithm is not available.
|
||||
*/
|
||||
public RSAPrivateKeyLoader() {
|
||||
try {
|
||||
this.decoder = Base64.getDecoder();
|
||||
this.keyFactory = KeyFactory.getInstance("RSA");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new KeyLoadingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an RSA private key from a given PEM formatted key text.
|
||||
* <p>
|
||||
* This method extracts the raw key content from the provided PEM text, decodes the
|
||||
* Base64-encoded content, and generates an instance of {@link RSAPrivateKey}. If the key cannot
|
||||
* be loaded due to invalid specifications or types, a {@link KeyLoadingException} is thrown.
|
||||
*
|
||||
* @param pemKeyText the PEM formatted private key text
|
||||
* @return an instance of {@link RSAPrivateKey}
|
||||
* @throws KeyLoadingException if the key loading process encounters an error
|
||||
*/
|
||||
@Override
|
||||
public RSAPrivateKey loadPrivateKey(String pemKeyText) {
|
||||
// Extract the raw key content
|
||||
var rawKeyContent = CryptoUtil.getRawContent(pemKeyText);
|
||||
|
||||
// Decode the Base64-encoded content
|
||||
var keyBytes = decoder.decode(rawKeyContent);
|
||||
|
||||
// Create a PKCS8EncodedKeySpec from the decoded bytes
|
||||
var keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
|
||||
try {
|
||||
// Get an RSA KeyFactory and generate the private key
|
||||
var _key = keyFactory.generatePrivate(keySpec);
|
||||
if (_key instanceof RSAPrivateKey key) {
|
||||
return key;
|
||||
} else {
|
||||
throw new KeyLoadingException("Unable to load private key from pem-formatted key text.");
|
||||
}
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new KeyLoadingException("Key spec is invalid.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-58
@@ -15,35 +15,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.security.impl;
|
||||
package com.onixbyte.crypto.algorithm.rsa;
|
||||
|
||||
import com.onixbyte.security.KeyLoader;
|
||||
import com.onixbyte.security.exception.KeyLoadingException;
|
||||
import com.onixbyte.crypto.PublicKeyLoader;
|
||||
import com.onixbyte.crypto.exception.KeyLoadingException;
|
||||
import com.onixbyte.crypto.util.CryptoUtil;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.*;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* A class responsible for loading RSA keys from PEM formatted text.
|
||||
* <p>
|
||||
* This class implements the {@link KeyLoader} interface and provides methods to load both private
|
||||
* and public RSA keys. The keys are expected to be in the standard PEM format, which includes
|
||||
* Base64-encoded key content surrounded by header and footer lines. The class handles the decoding
|
||||
* of Base64 content and the generation of keys using the RSA key factory.
|
||||
* <p>
|
||||
* Any exceptions encountered during the loading process are encapsulated in a
|
||||
* {@link KeyLoadingException}, allowing for flexible error handling.
|
||||
*
|
||||
* @author siujamo
|
||||
* @see KeyLoader
|
||||
* @see KeyLoadingException
|
||||
*/
|
||||
public class RSAKeyLoader implements KeyLoader {
|
||||
public class RSAPublicKeyLoader implements PublicKeyLoader {
|
||||
|
||||
private final Base64.Decoder decoder;
|
||||
|
||||
@@ -57,7 +45,7 @@ public class RSAKeyLoader implements KeyLoader {
|
||||
* This constructor initialises the Base64 decoder and the RSA {@link KeyFactory}. It may throw
|
||||
* a {@link KeyLoadingException} if the RSA algorithm is not available.
|
||||
*/
|
||||
public RSAKeyLoader() {
|
||||
public RSAPublicKeyLoader() {
|
||||
try {
|
||||
this.decoder = Base64.getDecoder();
|
||||
this.urlDecoder = Base64.getUrlDecoder();
|
||||
@@ -67,41 +55,6 @@ public class RSAKeyLoader implements KeyLoader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an RSA private key from a given PEM formatted key text.
|
||||
* <p>
|
||||
* This method extracts the raw key content from the provided PEM text, decodes the
|
||||
* Base64-encoded content, and generates an instance of {@link RSAPrivateKey}. If the key cannot
|
||||
* be loaded due to invalid specifications or types, a {@link KeyLoadingException} is thrown.
|
||||
*
|
||||
* @param pemKeyText the PEM formatted private key text
|
||||
* @return an instance of {@link RSAPrivateKey}
|
||||
* @throws KeyLoadingException if the key loading process encounters an error
|
||||
*/
|
||||
@Override
|
||||
public RSAPrivateKey loadPrivateKey(String pemKeyText) {
|
||||
// Extract the raw key content
|
||||
var rawKeyContent = getRawContent(pemKeyText);
|
||||
|
||||
// Decode the Base64-encoded content
|
||||
var keyBytes = decoder.decode(rawKeyContent);
|
||||
|
||||
// Create a PKCS8EncodedKeySpec from the decoded bytes
|
||||
var keySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
|
||||
try {
|
||||
// Get an RSA KeyFactory and generate the private key
|
||||
var _key = keyFactory.generatePrivate(keySpec);
|
||||
if (_key instanceof RSAPrivateKey key) {
|
||||
return key;
|
||||
} else {
|
||||
throw new KeyLoadingException("Unable to load private key from pem-formatted key text.");
|
||||
}
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new KeyLoadingException("Key spec is invalid.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an RSA public key from a given PEM formatted key text.
|
||||
* <p>
|
||||
@@ -116,7 +69,7 @@ public class RSAKeyLoader implements KeyLoader {
|
||||
@Override
|
||||
public RSAPublicKey loadPublicKey(String pemKeyText) {
|
||||
// Extract the raw key content
|
||||
var rawKeyContent = getRawContent(pemKeyText);
|
||||
var rawKeyContent = CryptoUtil.getRawContent(pemKeyText);
|
||||
|
||||
// Decode the Base64-encoded content
|
||||
var keyBytes = decoder.decode(rawKeyContent);
|
||||
+3
-3
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.security.exception;
|
||||
package com.onixbyte.crypto.exception;
|
||||
|
||||
/**
|
||||
* The {@code KeyLoadingException} class represents an exception that is thrown when there is an
|
||||
@@ -29,7 +29,7 @@ package com.onixbyte.security.exception;
|
||||
* <p><b>Example usage:</b></p>
|
||||
* <pre>{@code
|
||||
* try {
|
||||
* KeyLoader keyLoader = new EcKeyLoader();
|
||||
* PrivateKeyLoader keyLoader = new ECPrivateKeyLoader();
|
||||
* ECPrivateKey privateKey = keyLoader.loadPrivateKey(pemPrivateKey);
|
||||
* } catch (KeyLoadingException e) {
|
||||
* // Handle the exception
|
||||
@@ -38,7 +38,7 @@ package com.onixbyte.security.exception;
|
||||
* }</pre>
|
||||
*
|
||||
* @author zihluwang
|
||||
* @version 2.0.0
|
||||
* @version 3.0.0
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public class KeyLoadingException extends RuntimeException {
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.crypto.util;
|
||||
|
||||
public final class CryptoUtil {
|
||||
|
||||
private CryptoUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the raw content of a PEM formatted key by removing unnecessary headers, footers,
|
||||
* and new line characters.
|
||||
*
|
||||
* <p>
|
||||
* This method processes the provided PEM key text to return a cleaned string that contains
|
||||
* only the key content. The method strips away the
|
||||
* {@code "-----BEGIN (EC )?(PRIVATE|PUBLIC) KEY-----"} and
|
||||
* {@code "-----END (EC )?(PRIVATE|PUBLIC) KEY-----"} lines, as well as any new line characters,
|
||||
* resulting in a continuous string representation of the key, which can be used for further
|
||||
* cryptographic operations.
|
||||
*
|
||||
* @param pemKeyText the PEM formatted key as a string, which may include headers, footers and
|
||||
* line breaks
|
||||
* @return a string containing the raw key content devoid of any unnecessary formatting
|
||||
* or whitespace
|
||||
*/
|
||||
public static String getRawContent(String pemKeyText) {
|
||||
// remove all unnecessary parts of the pem key text
|
||||
return pemKeyText
|
||||
.replaceAll("-----BEGIN ((EC )|(RSA ))?(PRIVATE|PUBLIC) KEY-----", "")
|
||||
.replaceAll("-----END ((EC )|(RSA ))?(PRIVATE|PUBLIC) KEY-----", "")
|
||||
.replaceAll("\n", "");
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -4,7 +4,7 @@
|
||||
|
||||
Module `guid` serves as a guid creator for other `JDevKit` modules. You can also use this module as a guid creator standards.
|
||||
|
||||
We have already implemented `SnowflakeGuidCreator`, you can also implement a custom guid creations by implementing `com.onixbyte.guid.GuidCreator`.
|
||||
We have already implemented `SnowflakeGuidCreator`, you can also implement a custom guid creations by implementing `com.onixbyte.identitygenerator.IdentityGenerator`.
|
||||
|
||||
## Example usage
|
||||
|
||||
@@ -70,7 +70,7 @@ publishing {
|
||||
version = artefactVersion
|
||||
|
||||
pom {
|
||||
name = "OnixByte Identity Generator"
|
||||
name = "DevKit - GUID"
|
||||
description = "The module for generating GUIDs of JDevKit."
|
||||
url = projectUrl
|
||||
|
||||
@@ -82,8 +82,8 @@ publishing {
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
connection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
url = projectGithubUrl
|
||||
}
|
||||
|
||||
@@ -122,4 +122,4 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -15,10 +15,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.guid;
|
||||
package com.onixbyte.identitygenerator;
|
||||
|
||||
/**
|
||||
* The {@code GuidCreator} is a generic interface for generating globally unique identifiers (GUIDs)
|
||||
* The {@code IdentityGenerator} is a generic interface for generating globally unique identifiers (GUIDs)
|
||||
* of a specific type.
|
||||
* <p>
|
||||
* The type of ID is determined by the class implementing this interface.
|
||||
@@ -26,7 +26,7 @@ package com.onixbyte.guid;
|
||||
*
|
||||
* <p><b>Example usage:</b></p>
|
||||
* <pre>{@code
|
||||
* public class StringGuidCreator implements GuidCreator<String> {
|
||||
* public class StringGuidCreator implements IdentityGenerator<String> {
|
||||
* private final AtomicLong counter = new AtomicLong();
|
||||
*
|
||||
* @Override
|
||||
@@ -37,7 +37,7 @@ package com.onixbyte.guid;
|
||||
*
|
||||
* public class Example {
|
||||
* public static void main(String[] args) {
|
||||
* GuidCreator<String> guidCreator = new StringGuidCreator();
|
||||
* IdentityGenerator<String> guidCreator = new StringGuidCreator();
|
||||
* String guid = guidCreator.nextId();
|
||||
* System.out.println("Generated GUID: " + guid);
|
||||
* }
|
||||
@@ -49,7 +49,7 @@ package com.onixbyte.guid;
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface GuidCreator<IdType> {
|
||||
public interface IdentityGenerator<IdType> {
|
||||
|
||||
/**
|
||||
* Generates and returns the next globally unique ID.
|
||||
@@ -58,4 +58,4 @@ public interface GuidCreator<IdType> {
|
||||
*/
|
||||
IdType nextId();
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.guid.exceptions;
|
||||
package com.onixbyte.identitygenerator.exceptions;
|
||||
|
||||
/**
|
||||
* The {@code TimingException} class represents an exception that is thrown when there is an error
|
||||
+6
-6
@@ -15,16 +15,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.guid.impl;
|
||||
package com.onixbyte.identitygenerator.impl;
|
||||
|
||||
import com.onixbyte.guid.GuidCreator;
|
||||
import com.onixbyte.identitygenerator.IdentityGenerator;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A {@code SequentialUuidCreator} is responsible for generating UUIDs following the UUID version 7 specification, which
|
||||
* A {@code SequentialUuidGenerator} is responsible for generating UUIDs following the UUID version 7 specification, which
|
||||
* combines a timestamp with random bytes to create time-ordered unique identifiers.
|
||||
* <p>
|
||||
* This implementation utilises a cryptographically strong {@link SecureRandom} instance to produce the random
|
||||
@@ -34,14 +34,14 @@ import java.util.UUID;
|
||||
* The generated UUID adheres strictly to the layout and variant bits of UUID version 7 as defined in the specification.
|
||||
* </p>
|
||||
*/
|
||||
public class SequentialUuidCreator implements GuidCreator<UUID> {
|
||||
public class SequentialUuidGenerator implements IdentityGenerator<UUID> {
|
||||
|
||||
private final SecureRandom random;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SequentialUuidCreator} with its own {@link SecureRandom} instance.
|
||||
* Constructs a new {@code SequentialUuidGenerator} with its own {@link SecureRandom} instance.
|
||||
*/
|
||||
public SequentialUuidCreator() {
|
||||
public SequentialUuidGenerator() {
|
||||
this.random = new SecureRandom();
|
||||
}
|
||||
|
||||
+8
-8
@@ -15,16 +15,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.guid.impl;
|
||||
package com.onixbyte.identitygenerator.impl;
|
||||
|
||||
import com.onixbyte.guid.GuidCreator;
|
||||
import com.onixbyte.guid.exceptions.TimingException;
|
||||
import com.onixbyte.identitygenerator.IdentityGenerator;
|
||||
import com.onixbyte.identitygenerator.exceptions.TimingException;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* The {@code SnowflakeGuidCreator} generates unique identifiers using the Snowflake algorithm,
|
||||
* The {@code SnowflakeIdentityGenerator} generates unique identifiers using the Snowflake algorithm,
|
||||
* which combines a timestamp, worker ID, and data centre ID to create 64-bit long integers. The bit
|
||||
* distribution for the generated IDs is as follows:
|
||||
* <ul>
|
||||
@@ -35,7 +35,7 @@ import java.time.ZoneId;
|
||||
* <li>12 bits for sequence number (per millisecond)</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* When initializing a {@link SnowflakeGuidCreator}, you must provide the worker ID and data centre
|
||||
* When initializing a {@link SnowflakeIdentityGenerator}, you must provide the worker ID and data centre
|
||||
* ID, ensuring they are within the valid range defined by the bit size. The generator maintains an
|
||||
* internal sequence number that increments for IDs generated within the same millisecond. If the
|
||||
* system clock moves backward, an exception is thrown to prevent generating IDs with
|
||||
@@ -45,7 +45,7 @@ import java.time.ZoneId;
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class SnowflakeGuidCreator implements GuidCreator<Long> {
|
||||
public final class SnowflakeIdentityGenerator implements IdentityGenerator<Long> {
|
||||
|
||||
/**
|
||||
* Constructs a SnowflakeGuidGenerator with the default start epoch and custom worker ID, data
|
||||
@@ -54,7 +54,7 @@ public final class SnowflakeGuidCreator implements GuidCreator<Long> {
|
||||
* @param dataCentreId the data centre ID (between 0 and 31)
|
||||
* @param workerId the worker ID (between 0 and 31)
|
||||
*/
|
||||
public SnowflakeGuidCreator(long dataCentreId, long workerId) {
|
||||
public SnowflakeIdentityGenerator(long dataCentreId, long workerId) {
|
||||
this(dataCentreId, workerId, DEFAULT_CUSTOM_EPOCH);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public final class SnowflakeGuidCreator implements GuidCreator<Long> {
|
||||
* @throws IllegalArgumentException if the start epoch is greater than the current timestamp,
|
||||
* or if the worker ID or data centre ID is out of range
|
||||
*/
|
||||
public SnowflakeGuidCreator(long dataCentreId, long workerId, long startEpoch) {
|
||||
public SnowflakeIdentityGenerator(long dataCentreId, long workerId, long startEpoch) {
|
||||
if (startEpoch > currentTimestamp()) {
|
||||
throw new IllegalArgumentException("Start Epoch can not be greater than current timestamp!");
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
@@ -55,10 +55,10 @@ dependencies {
|
||||
compileOnly(libs.slf4j)
|
||||
implementation(libs.logback)
|
||||
|
||||
api(project(":devkit-utils"))
|
||||
api(project(":guid"))
|
||||
api(project(":key-pair-loader"))
|
||||
api(project(":simple-jwt-facade"))
|
||||
api(project(":common-toolbox"))
|
||||
api(project(":identity-generator"))
|
||||
api(project(":crypto-toolbox"))
|
||||
api(project(":jwt-toolbox-facade"))
|
||||
api(libs.jackson.databind)
|
||||
api(libs.jwt.core)
|
||||
|
||||
@@ -78,7 +78,7 @@ publishing {
|
||||
version = artefactVersion
|
||||
|
||||
pom {
|
||||
name = "OnixByte JWT Toolbox :: Auth0 Implementation"
|
||||
name = "Simple JWT :: Auth0"
|
||||
description = "Simple JWT implemented with com.auth0:java-jwt."
|
||||
url = projectUrl
|
||||
|
||||
@@ -90,8 +90,8 @@ publishing {
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
connection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
url = projectGithubUrl
|
||||
}
|
||||
|
||||
@@ -130,4 +130,4 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -17,9 +17,9 @@
|
||||
|
||||
package com.onixbyte.simplejwt.authzero;
|
||||
|
||||
import com.onixbyte.crypto.algorithm.ecdsa.ECPrivateKeyLoader;
|
||||
import com.onixbyte.devkit.utils.Base64Util;
|
||||
import com.onixbyte.guid.GuidCreator;
|
||||
import com.onixbyte.security.impl.ECKeyLoader;
|
||||
import com.onixbyte.identitygenerator.IdentityGenerator;
|
||||
import com.onixbyte.simplejwt.TokenPayload;
|
||||
import com.onixbyte.simplejwt.TokenResolver;
|
||||
import com.onixbyte.simplejwt.annotations.ExcludeFromPayload;
|
||||
@@ -92,7 +92,7 @@ import java.util.function.Function;
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.1
|
||||
* @see GuidCreator
|
||||
* @see IdentityGenerator
|
||||
* @see Algorithm
|
||||
* @see JWTVerifier
|
||||
* @see JWTCreator
|
||||
@@ -118,9 +118,9 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* GuidCreator used for generating unique identifiers for "jti" claim in JWT tokens.
|
||||
* IdentityGenerator used for generating unique identifiers for "jti" claim in JWT tokens.
|
||||
*/
|
||||
private GuidCreator<?> jtiCreator;
|
||||
private IdentityGenerator<?> jtiCreator;
|
||||
|
||||
/**
|
||||
* The algorithm used for signing and verifying JWT tokens.
|
||||
@@ -177,8 +177,8 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder keyPair(String publicKey, String privateKey) {
|
||||
var keyLoader = new ECKeyLoader();
|
||||
this.publicKey = keyLoader.loadPublicKey(publicKey);
|
||||
var keyLoader = new ECPrivateKeyLoader();
|
||||
// this.publicKey = keyLoader.loadPublicKey(publicKey);
|
||||
this.privateKey = keyLoader.loadPrivateKey(privateKey);
|
||||
return this;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
||||
* @param jtiCreator a creator to create JWT id
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder jtiCreator(GuidCreator<?> jtiCreator) {
|
||||
public Builder jtiCreator(IdentityGenerator<?> jtiCreator) {
|
||||
this.jtiCreator = jtiCreator;
|
||||
return this;
|
||||
}
|
||||
@@ -597,9 +597,9 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
||||
}
|
||||
|
||||
/**
|
||||
* GuidCreator used for generating unique identifiers for "jti" claim in JWT tokens.
|
||||
* IdentityGenerator used for generating unique identifiers for "jti" claim in JWT tokens.
|
||||
*/
|
||||
private final GuidCreator<?> jtiCreator;
|
||||
private final IdentityGenerator<?> jtiCreator;
|
||||
|
||||
/**
|
||||
* The algorithm used for signing and verifying JWT tokens.
|
||||
@@ -647,7 +647,7 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
||||
* @param issuer the person or organisation who issued this JWT
|
||||
* @param objectMapper a mapper for handling JSON serialisation and deserialization
|
||||
*/
|
||||
private AuthzeroTokenResolver(GuidCreator<?> jtiCreator, Algorithm algorithm, String issuer, ObjectMapper objectMapper) {
|
||||
private AuthzeroTokenResolver(IdentityGenerator<?> jtiCreator, Algorithm algorithm, String issuer, ObjectMapper objectMapper) {
|
||||
this.jtiCreator = jtiCreator;
|
||||
this.algorithm = algorithm;
|
||||
this.issuer = issuer;
|
||||
File renamed without changes.
+6
@@ -17,6 +17,12 @@
|
||||
|
||||
package com.onixbyte.simplejwt.authzero.test;
|
||||
|
||||
import com.onixbyte.simplejwt.authzero.AuthzeroTokenResolver;
|
||||
import com.onixbyte.simplejwt.constants.TokenAlgorithm;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* TestAuthzeroTokenResolver
|
||||
*
|
||||
File renamed without changes.
@@ -55,8 +55,8 @@ dependencies {
|
||||
compileOnly(libs.slf4j)
|
||||
implementation(libs.logback)
|
||||
|
||||
api(project(":devkit-utils"))
|
||||
api(project(":guid"))
|
||||
api(project(":common-toolbox"))
|
||||
api(project(":identity-generator"))
|
||||
|
||||
testImplementation(platform(libs.junit.bom))
|
||||
testImplementation(libs.junit.jupiter)
|
||||
@@ -74,7 +74,7 @@ publishing {
|
||||
version = artefactVersion
|
||||
|
||||
pom {
|
||||
name = "OnixByte JWT Toolbox :: Facade"
|
||||
name = "Simple JWT :: Facade"
|
||||
description = "Declaration of simple JWT module."
|
||||
url = projectUrl
|
||||
|
||||
@@ -86,8 +86,8 @@ publishing {
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
connection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
url = projectGithubUrl
|
||||
}
|
||||
|
||||
@@ -126,4 +126,4 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-2
@@ -66,7 +66,7 @@ implementation 'com.onixbyte:simple-jwt-spring-boot-starter:${simple-jwt-spring-
|
||||
|
||||
We need a `GuidCreator` instance to create JWT ID, though we did implemented a simple `GuidCreator`, but you can still customize it.
|
||||
|
||||
First, please implement the `com.onixbyte.guid.GuidCreator` interface based on your own rules for generating JWT IDs.
|
||||
First, please implement the `com.onixbyte.identitygenerator.IdentityGenerator` interface based on your own rules for generating JWT IDs.
|
||||
|
||||
Then, add the instance of your own guid creator to spring container, whose name is `jtiCreator`.
|
||||
|
||||
@@ -98,4 +98,4 @@ public GuidCreator<?> jtiCreator() {
|
||||
|
||||
If you have any suggestions, ideas, don't hesitate contacting us via [GitHub Issues](https://github.com/CodeCraftersCN/jdevkit/issues/new) or [Discord Community](https://discord.gg/NQK9tjcBB8).
|
||||
|
||||
If you face any bugs while using our library and you are able to fix any bugs in our library, we would be happy to accept pull requests from you on [GitHub](https://github.com/CodeCraftersCN/jdevkit/compare).
|
||||
If you face any bugs while using our library and you are able to fix any bugs in our library, we would be happy to accept pull requests from you on [GitHub](https://github.com/CodeCraftersCN/jdevkit/compare).
|
||||
+7
-7
@@ -55,9 +55,9 @@ dependencies {
|
||||
compileOnly(libs.slf4j)
|
||||
implementation(libs.logback)
|
||||
|
||||
api(project(":guid"))
|
||||
api(project(":simple-jwt-facade"))
|
||||
api(project(":simple-jwt-authzero"))
|
||||
api(project(":identity-generator"))
|
||||
api(project(":jwt-toolbox-facade"))
|
||||
api(project(":jwt-toolbox-auth0"))
|
||||
implementation(libs.springBoot.autoconfigure)
|
||||
implementation(libs.springBoot.starter.logging)
|
||||
implementation(libs.springBoot.configurationProcessor)
|
||||
@@ -87,7 +87,7 @@ publishing {
|
||||
version = artefactVersion
|
||||
|
||||
pom {
|
||||
name = "OnixByte JWT Toolbox :: Spring Boot Starter"
|
||||
name = "Simple JWT :: Spring Boot Starter"
|
||||
description = "Simple JWT all-in-one package for Spring Boot."
|
||||
url = projectUrl
|
||||
|
||||
@@ -99,8 +99,8 @@ publishing {
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
connection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
url = projectGithubUrl
|
||||
}
|
||||
|
||||
@@ -139,4 +139,4 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -17,7 +17,7 @@
|
||||
|
||||
package com.onixbyte.simplejwt.autoconfiguration;
|
||||
|
||||
import com.onixbyte.guid.GuidCreator;
|
||||
import com.onixbyte.identitygenerator.IdentityGenerator;
|
||||
import com.onixbyte.simplejwt.TokenResolver;
|
||||
import com.onixbyte.simplejwt.authzero.AuthzeroTokenResolver;
|
||||
import com.onixbyte.simplejwt.autoconfiguration.properties.SimpleJwtProperties;
|
||||
@@ -60,7 +60,7 @@ import org.springframework.context.annotation.Bean;
|
||||
@EnableConfigurationProperties(value = {SimpleJwtProperties.class})
|
||||
@ConditionalOnClass({DecodedJWT.class, AuthzeroTokenResolver.class})
|
||||
@ConditionalOnMissingBean({TokenResolver.class})
|
||||
@ConditionalOnBean(value = {GuidCreator.class}, name = "jtiCreator")
|
||||
@ConditionalOnBean(value = {IdentityGenerator.class}, name = "jtiCreator")
|
||||
@AutoConfigureAfter(value = GuidAutoConfiguration.class)
|
||||
public class AuthzeroTokenResolverAutoConfiguration {
|
||||
|
||||
@@ -76,7 +76,7 @@ public class AuthzeroTokenResolverAutoConfiguration {
|
||||
*/
|
||||
@Autowired
|
||||
public AuthzeroTokenResolverAutoConfiguration(SimpleJwtProperties simpleJwtProperties,
|
||||
@Qualifier("jtiCreator") GuidCreator<?> jtiCreator,
|
||||
@Qualifier("jtiCreator") IdentityGenerator<?> jtiCreator,
|
||||
ObjectMapper objectMapper) {
|
||||
this.jtiCreator = jtiCreator;
|
||||
this.simpleJwtProperties = simpleJwtProperties;
|
||||
@@ -86,7 +86,7 @@ public class AuthzeroTokenResolverAutoConfiguration {
|
||||
/**
|
||||
* Creates a new {@link TokenResolver} bean using {@link AuthzeroTokenResolver} if no existing
|
||||
* {@link TokenResolver} bean is found. The {@link AuthzeroTokenResolver} is configured with the
|
||||
* provided {@link GuidCreator}, {@code algorithm}, {@code issuer}, and {@code secret}
|
||||
* provided {@link IdentityGenerator}, {@code algorithm}, {@code issuer}, and {@code secret}
|
||||
* properties from {@link SimpleJwtProperties}.
|
||||
*
|
||||
* @return the {@link TokenResolver} instance
|
||||
@@ -110,7 +110,7 @@ public class AuthzeroTokenResolverAutoConfiguration {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private final GuidCreator<?> jtiCreator;
|
||||
private final IdentityGenerator<?> jtiCreator;
|
||||
|
||||
private final SimpleJwtProperties simpleJwtProperties;
|
||||
|
||||
+3
-3
@@ -17,7 +17,7 @@
|
||||
|
||||
package com.onixbyte.simplejwt.autoconfiguration;
|
||||
|
||||
import com.onixbyte.guid.GuidCreator;
|
||||
import com.onixbyte.identitygenerator.IdentityGenerator;
|
||||
import com.onixbyte.simplejwt.autoconfiguration.conditions.GuidCreatorCondition;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -28,7 +28,7 @@ import org.springframework.context.annotation.Conditional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Autoconfiguration for injecting a {@link GuidCreator} for generating jwt id.
|
||||
* Autoconfiguration for injecting a {@link IdentityGenerator} for generating jwt id.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
@@ -52,7 +52,7 @@ public class GuidAutoConfiguration {
|
||||
*/
|
||||
@Bean(name = "jtiCreator")
|
||||
@Conditional(GuidCreatorCondition.class)
|
||||
public GuidCreator<?> jtiCreator() {
|
||||
public IdentityGenerator<?> jtiCreator() {
|
||||
return UUID::randomUUID;
|
||||
}
|
||||
|
||||
+3
-3
@@ -17,7 +17,7 @@
|
||||
|
||||
package com.onixbyte.simplejwt.autoconfiguration.conditions;
|
||||
|
||||
import com.onixbyte.guid.GuidCreator;
|
||||
import com.onixbyte.identitygenerator.IdentityGenerator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Condition;
|
||||
@@ -46,7 +46,7 @@ public class GuidCreatorCondition implements Condition {
|
||||
/**
|
||||
* The condition to create bean {@code jtiCreator}.
|
||||
* <p>
|
||||
* If Spring does not have a bean of type {@link GuidCreator} named {@code jtiCreator} in the
|
||||
* If Spring does not have a bean of type {@link IdentityGenerator} named {@code jtiCreator} in the
|
||||
* application context, then create {@code jtiCreator}.
|
||||
*
|
||||
* @param context the spring application context
|
||||
@@ -59,7 +59,7 @@ public class GuidCreatorCondition implements Condition {
|
||||
final var beanFactory = Objects.requireNonNull(context.getBeanFactory());
|
||||
var isContainJtiCreator = beanFactory.containsBean("jtiCreator");
|
||||
if (isContainJtiCreator) {
|
||||
return !(beanFactory.getBean("jtiCreator") instanceof GuidCreator<?>);
|
||||
return !(beanFactory.getBean("jtiCreator") instanceof IdentityGenerator<?>);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.security;
|
||||
|
||||
import com.onixbyte.security.exception.KeyLoadingException;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
/**
|
||||
* The {@code KeyLoader} class provides utility methods for loading keys pairs from PEM-formatted
|
||||
* key text. This class supports loading both private and public keys.
|
||||
* <p>
|
||||
* The utility methods in this class are useful for scenarios where ECDSA keys need to be loaded
|
||||
* from PEM-formatted strings for cryptographic operations.
|
||||
*
|
||||
* @author zihluwang
|
||||
* @version 2.0.0
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public interface KeyLoader {
|
||||
|
||||
/**
|
||||
* Load private key from pem-formatted key text.
|
||||
*
|
||||
* @param pemKeyText pem-formatted key text
|
||||
* @return loaded private key
|
||||
*/
|
||||
PrivateKey loadPrivateKey(String pemKeyText);
|
||||
|
||||
/**
|
||||
* Load public key from pem-formatted key text.
|
||||
*
|
||||
* @param pemKeyText pem-formatted key text
|
||||
* @return loaded private key
|
||||
*/
|
||||
PublicKey loadPublicKey(String pemKeyText);
|
||||
|
||||
/**
|
||||
* Loads an RSA public key using the provided modulus and exponent.
|
||||
* <p>
|
||||
* This default implementation throws a {@link KeyLoadingException} to signify that this key loader does not support
|
||||
* loading an RSA public key. Implementing classes are expected to override this method to supply their own
|
||||
* loading logic.
|
||||
*
|
||||
* @param modulus the modulus value of the RSA public key, usually represented in hexadecimal or Base64
|
||||
* string format
|
||||
* @param exponent the public exponent value of the RSA public key, usually represented in hexadecimal or Base64
|
||||
* string format
|
||||
* @return the loaded {@link RSAPublicKey} instance
|
||||
* @throws KeyLoadingException if loading is not supported or fails
|
||||
*/
|
||||
default RSAPublicKey loadPublicKey(String modulus, String exponent) {
|
||||
throw new KeyLoadingException("This key loader does not support loading an RSA public key.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an EC public key using the provided x and y coordinates together with the curve name.
|
||||
* <p>
|
||||
* This default implementation throws a {@link KeyLoadingException} to signify that this key loader does not support
|
||||
* loading an EC public key. Implementing classes are expected to override this method to supply their own
|
||||
* loading logic.
|
||||
*
|
||||
* @param xHex the hexadecimal string representing the x coordinate of the EC point
|
||||
* @param yHex the hexadecimal string representing the y coordinate of the EC point
|
||||
* @param curveName the name of the elliptic curve
|
||||
* @return the loaded {@link ECPublicKey} instance
|
||||
* @throws KeyLoadingException if loading is not supported or fails
|
||||
*/
|
||||
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,
|
||||
* and new line characters.
|
||||
*
|
||||
* <p>
|
||||
* This method processes the provided PEM key text to return a cleaned string that contains
|
||||
* only the key content. The method strips away the
|
||||
* {@code "-----BEGIN (EC )?(PRIVATE|PUBLIC) KEY-----"} and
|
||||
* {@code "-----END (EC )?(PRIVATE|PUBLIC) KEY-----"} lines, as well as any new line characters,
|
||||
* resulting in a continuous string representation of the key, which can be used for further
|
||||
* cryptographic operations.
|
||||
*
|
||||
* @param pemKeyText the PEM formatted key as a string, which may include headers, footers and
|
||||
* line breaks
|
||||
* @return a string containing the raw key content devoid of any unnecessary formatting
|
||||
* or whitespace
|
||||
*/
|
||||
default String getRawContent(String pemKeyText) {
|
||||
// remove all unnecessary parts of the pem key text
|
||||
return pemKeyText
|
||||
.replaceAll("-----BEGIN ((EC )|(RSA ))?(PRIVATE|PUBLIC) KEY-----", "")
|
||||
.replaceAll("-----END ((EC )|(RSA ))?(PRIVATE|PUBLIC) KEY-----", "")
|
||||
.replaceAll("\n", "");
|
||||
}
|
||||
|
||||
}
|
||||
File renamed without changes.
@@ -70,7 +70,7 @@ publishing {
|
||||
version = artefactVersion
|
||||
|
||||
pom {
|
||||
name = "OnixByte Math Toolbox"
|
||||
name = "Num4j"
|
||||
description =
|
||||
"This module is an easy-to-use util for mathematical calculations in Java."
|
||||
url = projectUrl
|
||||
@@ -83,8 +83,8 @@ publishing {
|
||||
}
|
||||
|
||||
scm {
|
||||
connection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
developerConnection = "scm:git:git://github.com:onixbyte/onixbyte-toolbox.git"
|
||||
connection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
developerConnection = "scm:git:git://github.com:OnixByte/JDevKit.git"
|
||||
url = projectGithubUrl
|
||||
}
|
||||
|
||||
@@ -123,4 +123,4 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+8
-8
@@ -18,12 +18,12 @@
|
||||
rootProject.name = "onixbyte-toolbox"
|
||||
|
||||
include(
|
||||
"devkit-bom",
|
||||
"devkit-utils",
|
||||
"guid",
|
||||
"key-pair-loader",
|
||||
"num4j",
|
||||
"simple-jwt-facade",
|
||||
"simple-jwt-authzero",
|
||||
"simple-jwt-spring-boot-starter",
|
||||
"version-catalogue",
|
||||
"common-toolbox",
|
||||
"identity-generator",
|
||||
"crypto-toolbox",
|
||||
"math-toolbox",
|
||||
"jwt-toolbox-facade",
|
||||
"jwt-toolbox-auth0",
|
||||
"jwt-toolbox-spring-boot-starter",
|
||||
)
|
||||
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user