Reputation: 1401
Is it possible to read the RSA private key of format PKCS1 in JAVA without converting to PKCS8? if yes, sample code is appreciated.
-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----
Upvotes: 19
Views: 24721
Reputation: 5549
As hinted here, there is a solution without BouncyCastle
.
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
public class Pkcs1ToPkcs8 {
private static final String PRIVATE_KEY = """
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAkiAWsNL5sQqkDi04soEEOGiZQ7LlB91Z3jh1uHFByXXixHVC
VwuahgAWxJ345G6AZVqgPxLnopPh513kXTPWRMggC6HszU+jQp3fkNo7OnzMhQcP
...
-----END RSA PRIVATE KEY-----
""";
public static void main(String[] args) throws Exception {
var pem = PRIVATE_KEY
.replaceAll("-----.+KEY-----", "")
.replaceAll("\\s+", "");
var bytes = Base64.getDecoder().decode(pem);
bytes = buildPkcs8KeyFromPkcs1Key(bytes);
var keyFactory = KeyFactory.getInstance("RSA");
var keySpec = new PKCS8EncodedKeySpec(bytes);
var privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
System.out.println(privateKey);
}
private static byte[] buildPkcs8KeyFromPkcs1Key(byte[] innerKey) {
var result = new byte[innerKey.length + 26];
System.arraycopy(Base64.getDecoder().decode("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKY="), 0, result, 0, 26);
System.arraycopy(BigInteger.valueOf(result.length - 4).toByteArray(), 0, result, 2, 2);
System.arraycopy(BigInteger.valueOf(innerKey.length).toByteArray(), 0, result, 24, 2);
System.arraycopy(innerKey, 0, result, 26, innerKey.length);
return result;
}
}
Upvotes: 1
Reputation: 39241
Java does not come with out-of-the-box support for PKCS1 keys. You can however use Bouncycastle
PEMParser pemParser = new PEMParser(new FileReader(privateKeyFile));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
Object object = pemParser.readObject();
KeyPair kp = converter.getKeyPair((PEMKeyPair) object);
PrivateKey privateKey = kp.getPrivate();
Upvotes: 32