Search code examples
javakeystorekeytooljava-6

Extracting Certificate from Keystore on Java 6


I'm facing a problem right now and I can't understand why I can't read a KeyStore on Java 6. The piece code is like this:

KeyStore ks = KeyStore.getInstance("jks");
FileInputStream file = new FileInputStream(<path to file>);
ks.load(file, <password>);
String alias = (String)ks.aliases().nextElement();

PrivateKey key = (PrivateKey)ks.getKey(alias, ConstantsUtils.CERT_PASS.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);

I'm using this certificate to sign a PDF from Java code, but variables key and chain stay null, so the keystore can't retreive my private key.

The Keystore was created by keytool importing a certificate with the next line (Windows 7):

C:\Program Files\Java\jdk1.6.0_37\bin>keytool -importcert -file "<path to cert>" -keystore <path to keystore -alias "<alias>" -keypass <password> -storepass <password>

Imported certificate is from a third party, and should work properly. I don't know if is something wrong importing the certificate or if I'm coding something in a bad way.


Solution

  • Well, finally I found the ultimate solution.

    My problem was that I had 2 files, one a certificate (we'll call it certificate.crt) and the other one was the private key (we'll call it private_key.pem). As EJP said previously the problem was around the private key import process. I had 2 different files so I was importing just certificate.crt file into a .jks file, and private_key.pem gave me an error when I tried to import (obviously). So my solution was to merge both files (certificate.crt and private_key.pem) into one PKCS#12 file with this command:

    openssl pkcs12 -inkey private_key.pem -in certificate.cert -export -out certificate.pfx
    

    Now, the new certificate.pfx is a keystore which contains public and private key, correctly formated so, with some changes in my code it was possible to obtain the private key and sign my document:

    KeyStore ks = KeyStore.getInstance("PKCS12");
    FileInputStream file = new FileInputStream(<path to .pfx file>);
    ks.load(file, <password>);
    String alias = (String)ks.aliases().nextElement();
    
    PrivateKey key = (PrivateKey)ks.getKey(alias, ConstantsUtils.CERT_PASS.toCharArray());
    Certificate[] chain = ks.getCertificateChain(alias);
    

    So thats all. Thank you EJP, I was missunderstanding you, and you made me think in the right way. I was facing this four days so I'm pretty hyped up right now.