Reputation:
I would like to get "PrivateKey" from PEM file (PEM file contains keyPair), I am successfully able to read public key from PEM file (something same code shown below), but when I am reading PrivateKey, it's giving me following error
Exception in thread "main" java.lang.ClassCastException: sun.security.x509.X509CertImpl cannot be cast to java.security.PrivateKey
at com.bouncycastle.common.ReadPrivatePublicKeys.main(ReadPrivatePublicKeys.java:41)
I'm using bouncy latest version of bouncyCastle to read the private and public key
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.52</version>
</dependency>
The Java code which I've developed for reference. Any quick help what is going wrong here? Any BouncyCastle developer can help me?
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
public class ReadPrivatePublicKeys {
private static final String PEM_FILE="/home/user/user.pem";
public static void main(String[] args){
PemObject pemObject = null;
PrivateKey privateKey = null;
FileReader fileReader;
try {
fileReader = new FileReader(PEM_FILE);
PemReader pemReader = new PemReader(fileReader);
pemObject = pemReader.readPemObject();
if(!pemObject.getType().equalsIgnoreCase("CERTIFICATE")){
System.out.println("Does not contain a certificate");
}
final byte[] x509Dataprivate = pemObject.getContent();
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
privateKey = (PrivateKey) certificateFactory.generateCertificate(new ByteArrayInputStream(x509Dataprivate));
if(!(privateKey instanceof X509Certificate)){
System.out.println("Does not contain an X509 certificate");
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}catch (CertificateException e) {
e.printStackTrace();
}
System.out.println(privateKey);
}
}
Upvotes: 1
Views: 13605
Reputation: 11
This exception can be due to improper PEM format of reading cerKey file. Anyhow your current crtKey form is PEM only, but it need a extended form of PEM. You can try this -
openssl rsa -in cert.key -outform PEM -out cert.key
Upvotes: 1
Reputation: 400
I would assume that your PEM is similar to the output of this (no encrypt) openssl genrsa -out mykey.pem 2048
Your POM should look like this
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.52</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.52</version>
</dependency>
</dependencies>
Here are the code using PEMParser plugged from BC test suite
package com.nguyen.eledra;
import java.io.FileReader;
import java.security.PrivateKey;
import java.security.Security;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
public class Main {
private static final String PEM_FILE = "/home/xxxxx/mykey.pem";
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
FileReader fileReader;
try {
fileReader = new FileReader(PEM_FILE);
PEMParser parser = new PEMParser(fileReader);
PEMKeyPair kp = (PEMKeyPair) parser.readObject();
PrivateKeyInfo info = kp.getPrivateKeyInfo();
PrivateKey rdKey = new JcaPEMKeyConverter().setProvider("BC")
.getPrivateKey(info);
System.out.println(rdKey);
parser.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Upvotes: 2