diff --git a/key-pair-loader/src/main/java/com/onixbyte/security/KeyLoader.java b/key-pair-loader/src/main/java/com/onixbyte/security/KeyLoader.java index b299d5a..0c7a4a5 100644 --- a/key-pair-loader/src/main/java/com/onixbyte/security/KeyLoader.java +++ b/key-pair-loader/src/main/java/com/onixbyte/security/KeyLoader.java @@ -17,8 +17,11 @@ package com.onixbyte.security; +import com.onixbyte.security.exception.KeyLoadingException; + import java.security.PrivateKey; import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; /** * 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); + 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, * and new line characters. diff --git a/key-pair-loader/src/main/java/com/onixbyte/security/impl/RSAKeyLoader.java b/key-pair-loader/src/main/java/com/onixbyte/security/impl/RSAKeyLoader.java index 9520867..b0f5dc2 100644 --- a/key-pair-loader/src/main/java/com/onixbyte/security/impl/RSAKeyLoader.java +++ b/key-pair-loader/src/main/java/com/onixbyte/security/impl/RSAKeyLoader.java @@ -20,12 +20,14 @@ package com.onixbyte.security.impl; import com.onixbyte.security.KeyLoader; import com.onixbyte.security.exception.KeyLoadingException; +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.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; @@ -47,6 +49,9 @@ import java.util.Base64; public class RSAKeyLoader implements KeyLoader { private final Base64.Decoder decoder; + + private final Base64.Decoder urlDecoder; + private final KeyFactory keyFactory; /** @@ -58,6 +63,7 @@ public class RSAKeyLoader implements KeyLoader { public RSAKeyLoader() { try { this.decoder = Base64.getDecoder(); + this.urlDecoder = Base64.getUrlDecoder(); this.keyFactory = KeyFactory.getInstance("RSA"); } catch (NoSuchAlgorithmException e) { throw new KeyLoadingException(e); @@ -133,4 +139,22 @@ public class RSAKeyLoader implements KeyLoader { 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); + } + } }