Skip to content

Commit 998923e

Browse files
committed
feat: load RSA key pair from pem-formatted key text
1 parent fc94583 commit 998923e

File tree

5 files changed

+130
-50
lines changed

5 files changed

+130
-50
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright (C) 2024-2025 OnixByte.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
*
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.onixbyte.security.impl;
19+
20+
import com.onixbyte.security.KeyLoader;
21+
import com.onixbyte.security.exception.KeyLoadingException;
22+
23+
import java.security.KeyFactory;
24+
import java.security.NoSuchAlgorithmException;
25+
import java.security.interfaces.RSAPrivateKey;
26+
import java.security.interfaces.RSAPublicKey;
27+
import java.security.spec.InvalidKeySpecException;
28+
import java.security.spec.PKCS8EncodedKeySpec;
29+
import java.security.spec.X509EncodedKeySpec;
30+
import java.util.Base64;
31+
32+
public class RsaKeyLoader implements KeyLoader {
33+
34+
private final Base64.Decoder decoder;
35+
private final KeyFactory keyFactory;
36+
37+
public RsaKeyLoader() {
38+
try {
39+
this.decoder = Base64.getDecoder();
40+
this.keyFactory = KeyFactory.getInstance("RSA");
41+
} catch (NoSuchAlgorithmException e) {
42+
throw new KeyLoadingException(e);
43+
}
44+
}
45+
46+
@Override
47+
public RSAPrivateKey loadPrivateKey(String pemKeyText) {
48+
// Extract the raw key content
49+
var rawKeyContent = getRawContent(pemKeyText);
50+
51+
// Decode the Base64-encoded content
52+
var keyBytes = decoder.decode(rawKeyContent);
53+
54+
// Create a PKCS8EncodedKeySpec from the decoded bytes
55+
var keySpec = new PKCS8EncodedKeySpec(keyBytes);
56+
57+
try {
58+
// Get an RSA KeyFactory and generate the private key
59+
var _key = keyFactory.generatePrivate(keySpec);
60+
if (_key instanceof RSAPrivateKey key) {
61+
return key;
62+
} else {
63+
throw new KeyLoadingException("Unable to load private key from pem-formatted key text.");
64+
}
65+
} catch (InvalidKeySpecException e) {
66+
throw new KeyLoadingException("Key spec is invalid.", e);
67+
}
68+
}
69+
70+
@Override
71+
public RSAPublicKey loadPublicKey(String pemKeyText) {
72+
// Extract the raw key content
73+
var rawKeyContent = getRawContent(pemKeyText);
74+
75+
// Decode the Base64-encoded content
76+
var keyBytes = decoder.decode(rawKeyContent);
77+
78+
// Create an X509EncodedKeySpec from the decoded bytes
79+
var keySpec = new X509EncodedKeySpec(keyBytes);
80+
81+
// Get an RSA KeyFactory and generate the public key
82+
try {
83+
var _key = keyFactory.generatePublic(keySpec);
84+
if (_key instanceof RSAPublicKey key) {
85+
return key;
86+
} else {
87+
throw new KeyLoadingException("Unable to load public key from pem-formatted key text.");
88+
}
89+
} catch (InvalidKeySpecException e) {
90+
throw new KeyLoadingException("Key spec is invalid.", e);
91+
}
92+
}
93+
}

key-pair-loader/src/test/java/com/onixbyte/security/KeyPairLoaderTest.java

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

key-pair-loader/src/test/resources/ec_private_key_pkcs8.pem

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD4VIFYJFMAs15j
3+
J3V3IicHd7sI2TIFqTZME40zlOlVAlPKLZmTQvZFLNgaUAAsvPi5i1DR2ywwK6Al
4+
BfnwVnzvmDXC5mKHOz4oxOQVA6Nlp2yVaQMzidmfYNSkMtcv/4HRPsatc7K/M5l6
5+
pCP20DVRjkikBdIy8e9w+x6BrIFp5Q8PZc/X2BGNAUMMYACdeYH5R/A0CxqkND13
6+
esc4gkynMOrvZrZGHCz51usfSCqyDWWwsN+GG6LYWia4GkNlS0erQnP8gS93dfjl
7+
e96BIfy3z7Iv+kUrf5ikNW2P8jMxLAv6LO+dcUAu9k477wIAF7Iq5KMuH/otsDOu
8+
+h+2qXmBAgMBAAECggEAdRqcmC0g+y6arxV3fkObthjPGYAa57KBCWUa7B0n30+m
9+
pavVRS2Jpttb2SSqwG4ouI6rARti/iBEd9EWqTCP4AieKZetFOpqCJ24lPRPRGus
10+
d9S6jr5N4qut+vSCp37NABijZj4uJ540nTH0R7qtuhTnynl4Q0/1wwiYvTvVF1Lg
11+
dn+I/8aRbshwDhdAOWOUe6GL7/eaCYgN8/UmlKIpp8tg0w2iWxbaFiR7gZiM41LA
12+
M6SXXfcCas+ZVXsGbzQ3SNiVurCGuuRNcCScXS3/WoEDIb3cNtp49iOmQS+nmEoo
13+
wh4uiEd+0+BrzxngS4o5+mKnHJnwgY0+veGVYLMR5QKBgQD9WKQmevMDU5c+NPq9
14+
8jaR457Fuxq1gwzeFNJdWfOc/K2LEWh+nFNFCb++EboEj6FdxWaWNMxbrmJps5gs
15+
EoBUYy/Tl7UycDqDfiYLmDdTsf2pVjjh9jaIADiLcJ8S6wwJMZKub7Tp8UVkenAl
16+
535MqShLUC11Y7VxLb3Tsll4XwKBgQD67mm6iCmshr/eszPfNE3ylZ+PiNa7nat7
17+
N7lQzBIiRJflT1kmVidC5gE+jASqH728ChkZZKxbHsjxpmWdAhLOITdXoTB4sDsd
18+
wtV1lxkXxK9FnrpFvO3y1wZ/QsD3Z2KXxHYZqawkUETO9F3nqAXW0b2GDar5Qiyo
19+
J3Tx/43aHwKBgDC0NMJtCoDONhowZy/S+6iqQKC0qprQec3L5PErVMkOTnKYwyTr
20+
+pogGKt6ju9HiXcUdvdTaSIK8UJu00dNuzv94XjlBmGO78DNpJTAC4rcge5m9AKE
21+
qdEVcclkukARzbuKuy8rrHT4/CUn4J141m/4aRWpcUPLCluato6XD9ozAoGBANvf
22+
JhOFFgcPd3YazfvpZ9eE1XA+tfFlYYmxNRcgCU+vjO0oDvSxjutmgHae18N91pG6
23+
w21lskSRf/+GDwl5dKLbphOJsOA/gz07qDDGOf2CoRW+1Hcg6drcINxH0K+4DkLv
24+
qZApBSY4k2JH6zR+HMeztn6M4WBRZLHfCPC3PUN/AoGAA3AoHbLTZvqMIKSDkP4Y
25+
U/tTsSFDY4aYo7LG/jk8af3oPU3KyGh4ZFBd6aMmXbS8f8FjvmrM+/e+y9OOGAlq
26+
iOl0hYrs5cJSMLW6i4KnJYuYbMkgmk3bN2t9apu64xKR94gbPrI6AGnPZp+iIzp0
27+
hXKe4HcuhQ3G0a2hjayiQ84=
28+
-----END PRIVATE KEY-----
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+FSBWCRTALNeYyd1dyIn
3+
B3e7CNkyBak2TBONM5TpVQJTyi2Zk0L2RSzYGlAALLz4uYtQ0dssMCugJQX58FZ8
4+
75g1wuZihzs+KMTkFQOjZadslWkDM4nZn2DUpDLXL/+B0T7GrXOyvzOZeqQj9tA1
5+
UY5IpAXSMvHvcPsegayBaeUPD2XP19gRjQFDDGAAnXmB+UfwNAsapDQ9d3rHOIJM
6+
pzDq72a2Rhws+dbrH0gqsg1lsLDfhhui2FomuBpDZUtHq0Jz/IEvd3X45XvegSH8
7+
t8+yL/pFK3+YpDVtj/IzMSwL+izvnXFALvZOO+8CABeyKuSjLh/6LbAzrvoftql5
8+
gQIDAQAB
9+
-----END PUBLIC KEY-----

0 commit comments

Comments
 (0)