feat: load RSA public key via modulus and exponent

This commit is contained in:
siujamo
2025-06-09 11:49:57 +08:00
parent 6ac9f1ae49
commit e03cc180c9
2 changed files with 31 additions and 0 deletions
@@ -17,8 +17,11 @@
package com.onixbyte.security; package com.onixbyte.security;
import com.onixbyte.security.exception.KeyLoadingException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
/** /**
* The {@code KeyLoader} class provides utility methods for loading keys pairs from PEM-formatted * The {@code KeyLoader} class provides utility methods for loading keys pairs from PEM-formatted
@@ -49,6 +52,10 @@ public interface KeyLoader {
*/ */
PublicKey loadPublicKey(String pemKeyText); PublicKey loadPublicKey(String pemKeyText);
default RSAPublicKey loadPublicKey(String modulus, String exponent) {
throw new KeyLoadingException("This key loader does not support RSA Public key loading.");
}
/** /**
* 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,12 +20,14 @@ 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.KeyFactory; import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
import java.util.Base64; import java.util.Base64;
@@ -47,6 +49,9 @@ import java.util.Base64;
public class RSAKeyLoader implements KeyLoader { public class RSAKeyLoader implements KeyLoader {
private final Base64.Decoder decoder; private final Base64.Decoder decoder;
private final Base64.Decoder urlDecoder;
private final KeyFactory keyFactory; private final KeyFactory keyFactory;
/** /**
@@ -58,6 +63,7 @@ public class RSAKeyLoader implements KeyLoader {
public RSAKeyLoader() { public RSAKeyLoader() {
try { try {
this.decoder = Base64.getDecoder(); this.decoder = Base64.getDecoder();
this.urlDecoder = Base64.getUrlDecoder();
this.keyFactory = KeyFactory.getInstance("RSA"); this.keyFactory = KeyFactory.getInstance("RSA");
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new KeyLoadingException(e); throw new KeyLoadingException(e);
@@ -133,4 +139,22 @@ public class RSAKeyLoader implements KeyLoader {
throw new KeyLoadingException("Key spec is invalid.", e); throw new KeyLoadingException("Key spec is invalid.", e);
} }
} }
@Override
public RSAPublicKey loadPublicKey(String modulus, String exponent) {
try {
var _modulus = new BigInteger(1, urlDecoder.decode(modulus));
var _exponent = new BigInteger(1, urlDecoder.decode(exponent));
var keySpec = new RSAPublicKeySpec(_modulus, _exponent);
var kf = KeyFactory.getInstance("RSA");
if (kf.generatePublic(keySpec) instanceof RSAPublicKey rsaPublicKey) {
return rsaPublicKey;
} else {
throw new KeyLoadingException("Cannot generate RSA public key with given modulus and exponent.");
}
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new KeyLoadingException("Cannot generate RSA public key with given modulus and exponent.", e);
}
}
} }