18

I am testing SSL in java with SSLServerSocket and other classes in the java.ssl package. When I run the following code, I get the exception java.io.IOException: Invalid keystore format. My code:

package testing;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.security.KeyStore;

import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManager;

public class SSLServerTest {
    public static void main(String[] args) {
        try {
            int port = 3000;
            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            KeyStore ks = KeyStore.getInstance("JKS");
            InputStream ksIs = new FileInputStream("key.txt");
            try {
                ks.load(ksIs, "Bennett556".toCharArray());
            } finally {
                if (ksIs != null) {
                    ksIs.close();
                }
            }
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, "Bennett556".toCharArray());
            sc.init(kmf.getKeyManagers(), new TrustManager[] {}, null);
            ServerSocketFactory ssocketFactory = sc.getServerSocketFactory();
            SSLServerSocket ssocket = (SSLServerSocket) ssocketFactory
                    .createServerSocket(port);
            ssocket.setEnabledProtocols(new String[] { "SSLv3" });
            Socket socket = ssocket.accept();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            out.println("Hello, Securly!");
            out.close();
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

File key.txt: 1268312345812304612348712634283427346 I am guessing I should put something else in the key.txt file, but I do not know what to put in it. Probably a searilized object.

EDIT: Client Code:

package testing;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;

import javax.net.SocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;

public class SSLClientTest {
    public static void main(String[] args) {

        int port = 3000;
        String host = "localhost";

        try {
            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            KeyStore ks = KeyStore.getInstance("JKS");
            InputStream ksIs = new FileInputStream("key.txt");
            try {
                ks.load(ksIs, "Bennett556".toCharArray());
            } finally {
                if (ksIs != null) {
                    ksIs.close();
                }
            }
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, "Bennett556".toCharArray());
            sc.init(kmf.getKeyManagers(), new TrustManager[] {}, null);
            SocketFactory factory = sc.getSocketFactory();
            SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
            socket.startHandshake();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            String str = "";
            while ((str = in.readLine()) != null)
                System.out.println(str);
            in.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
2
  • A KeyStore file is not a text file. Commented Sep 27, 2014 at 6:16
  • In fact a key is not a key store; a text file is not a key store; and a key can't be stored in a text file. Commented Mar 17, 2017 at 3:01

12 Answers 12

24

I had exactly the same issue. Indeed, the keystore file was invalid and not related to the JDK//JRE version. The problem in my case was caused by Maven. I was using the following option in my pom file:

<resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

The "true" value in the filtering was messing with the key file. Therefore, the keyfile that was available in my classpath when Spring run was not exactly the same I had under my directory "src/main/resources" and that caused the Invalid Keystore Format exception. When I tested with keytool I was using the one under the "resources" folder so that was misleading the real issue.

Solving the issue: in your pom.xml file, change the value for "filtering" to "false". Another way of solving the issue was to specify explicitly the location of the keystore in the application.properties file. So instead of:

server.ssl.key-store: classpath:keystore.jks

I used

server.ssl.key-store: keystore/keystore.jks
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! This wasn't my exact problem, but it helped me resolve mine. I was "hot" building with my IDE over and over (for days), and seemingly randomly this issue started to happen. Your answer made me think to do a legit maven build, which allowed the next deploy to work :).
Thank you so much! I have spent a whole day stuck on this issue trying to get Kafka to work in my Spring app. You're a lifesaver.
12

For my case i have used different versions of keytool and java, once i switched to same jdk they got fixed.

1 Comment

Its same for me. I was using java 11 to generate the certs file and using them in java 8 so got the error. Once on same version, it resolved.
8

Your file is invalid. You have to import a JKS keystore file and not a txt one. You have to use the keytool to create your keystore file and then import this file.

6 Comments

It depends on which file types your keys are stored. Examples can be found here. If you have any questions/problems, feel free to ask.
I am assuming that you have't added the certificate of the server to the client. Send the code for client connection.
I changed my client (and server) code and now get the following exception on the client: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No X509TrustManager implementation available Caused by: java.security.cert.CertificateException: No X509TrustManager implementation available
@JavaIsCool That's a new question, but you specified an empty array of TrustManagers when you initialized your SSLContext, didn't you, so of course there are no TrustManagers available.
@VGe0rge How do I make a chain of certificates with the keytool command?
|
8

I faced with the same problem when load keystore with the following code:

KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
Resource resource = new ClassPathResource(file);
trustStore.load(resource.getInputStream(), password.toCharArray());

It turned out to be the JDK issue, it doesn't work with jre1.8.0_25. when I upgrade JDK version to the latest jre1.8.0_121, it works.

4 Comments

There is no such issue. You changed something else. When I saw 'low version JDK' I thought you meant 1.2.2. 1.8.0_66 is hardly 'low'.
Not 1.8.0_66, I made a mistake, it's my JDK version. It doesn't work on my colleague's jre1.8.0_25, relatively lower than 66 or the latest, reinstall the JDK is ok, you can try.
I encountered the same issue, fails with JDK 1.8.0_45, works fine with JDK 1.8.0_131
yep, same for me. It also appears when using the docker images of ibmjava vs the openjdk one. Not sure which version exactly causes the issue, but it's very likely that it is caused by the JDK version.
2

I was seeing this exception:

Invalid keystore format

while running a java application using JRE-1.8.0_40 on CentOS 6.6 64-bit linux.

On using JRE-1.8.0_172, the exception went away.

Comments

1

How did you generate the JKS file? I tried all suggested solutions but none worked for me. I was getting the same error when trying to read (in my code) a JKS file that I generated using OpenJDK Zulu 11's keytool.

I fixed this by instead generating the JKS file using the "KeyStore Explorer" tool, which I believe uses oracle JDK internally. Using the tool, I basically created a JKS file and added my trusted certificate to it.

I hope this helps.

1 Comment

you finally used KeyStore Explorer?
0

I recently had the same problem even though I was using a valid .jks file... the code used to work fine but suddenly it started giving "Invalid keystore format"

The answer given earlier to set the pom.xml resource filtering value to "false" worked for me too e.g.,

 <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
        </resource>
    </resources>

Comments

0

mac users

updating JDK in System Preferences -> JAVA -> JAVA Control Panel -> Update tab

from java version "1.8.0_231" to "1.8.0_333" fixed the issue

Comments

0

If you use openjdk:
Use openjdk version "11.0.17" or a newer one.

Comments

0

For me i used the absolute path with the file: prefix to make it work. when I used only the name of the file it was giving me invalid keystore format error.

I hope this helps.

  KeyStore keyStore = KeyStore.getInstance("JKS");
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext();
    Resource res = applicationContext.getResource("file:///Users/blibanos/Downloads/peoplefiles.jks");
    try (InputStream in = res.getInputStream()) {
        keyStore.load(in, password);
    }
    ```

Comments

0

For debugging purposes, here is the original code. https://github.com/openjdk/jdk/blob/9a9add8825a040565051a09010b29b099c2e7d49/jdk/src/share/classes/sun/security/provider/JavaKeyStore.java#L650

This was a big help to me. I was generating Java 11 certs and trying to use them with Java 8. Check your 0xFEED FEED (Magic) and 0x0002. These should be the first bytes of your jks. Or in int...

-2
-19
-2
-19
0
0
0
2

If your JKS doesn't start with that, you know you have a problem.

Comments

0

I found this worked for me on a Mac when I was having trouble with

keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore

Go to System Settings from the Apple menu and search for Java. A window will open with Java details. Check to see if an update is needed. After I updated Java, and ran the keytool command it worked fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.