java-8keystorex509keytoolpkcs#8

Java Invalid keystore format


I have a private key with PKCS#8 encoding format as .pem (and .cert) file.

If i try to call following method:

 private KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
     String ks = keystores.get(service);
     KeyStore keyStore = KeyStore.getInstance("JKS");
     keyStore.load(new Base64InputStream(new ByteArrayInputStream(ks.getBytes())), "secret".toCharArray());
     return keyStore;
 }

I get an error on line 4 "keystore.load...":

Caused by: java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source) ~[na:1.8.0_211]
at sun.security.provider.JavaKeyStore$JKS.engineLoad(Unknown Source) ~[na:1.8.0_211]
at sun.security.provider.KeyStoreDelegator.engineLoad(Unknown Source) ~[na:1.8.0_211]
at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(Unknown Source) ~[na:1.8.0_211]
at java.security.KeyStore.load(Unknown Source) ~[na:1.8.0_211]
at java_security_KeyStore$load$0.call(Unknown Source) ~[na:na]

How can i fix this problem? I read that java does not support PKCS#8 encoding format...

If i try to import key manually like this:

keytool -import -alias *alias* -keystore cacerts -file *cert.pem*

I get this error:

keytool error: java.lang.Exception: Input not an X.509 certificate

I tried to convert pkcs8 to x509 in openssl (with openvpn in windwos)... unsuccessful.

It works with the old key. If i replaced the old key with the new private key, then it fails..

How can i fix this error?


Solution

  • My mistake: i try to add the content (as string) of the private key. The correct way:

    At first create a PKCS12 file (replace content of * * with the path to your files.) with openssl (i used openvpn on windows):

    pkcs12 -inkey *key* -in *cert* -export -out myKeys.pkcs12
    

    Use only the certificates (in my case .der files).

    Import your keys into a keystore (.jks-file):

    keytool -importkeystore -srckeystore myKeys.pkcs12 -srcstoretype pkcs12 -destkeystore *keystoreName*
    

    For initialising a String with the "content" of .jks file i implement following code:

    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.io.FileUtils;
    
    import java.io.File;
    
    public class ClassName{
    
        public static void main(String[] args) {
            byte[] bytes = FileUtils.readFileToByteArray(new File("Path to .jks file"));
            String bdata = new String(Base64.encodeBase64(bytes, true));
            System.out.println(bdata);
        }
    }
    

    I take the printed lines and initialise the variable "ks" (see my code in the question) with it.