user4798111
user4798111

Reputation:

Exception in thread "main" java.lang.ClassCastException: sun.security.x509.X509CertImpl cannot be cast to java.security.PrivateKey

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

Answers (2)

nakul tyagi
nakul tyagi

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

Eledra Nguyen
Eledra Nguyen

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

Related Questions