SSL Java java.io.IOException: 无效的密钥库格式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26071429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 01:47:57  来源:igfitidea点击:

SSL Java java.io.IOException: Invalid keystore format

javasecurityssl

提问by Java Is Cool

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:

我正在使用 SSLServerSocket 和 java.ssl 包中的其他类在 java 中测试 SSL。当我运行以下代码时,出现异常 java.io.IOException: Invalid keystore format。我的代码:

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.

文件 key.txt: 1268312345812304612348712634283427346 我猜我应该在 key.txt 文件中放其他东西,但我不知道该放什么。可能是一个serilized对象。

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();
        }
    }
}

采纳答案by VGe0rge

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

您的文件无效。您必须导入 JKS 密钥库文件而不是 txt 文件。您必须使用keytool创建您的密钥库文件,然后导入此文件。

回答by Dave Pateral

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

load keystore使用以下代码时,我遇到了同样的问题:

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.

原来是 JDK 问题,它不适用于 jre1.8.0_25. 当我将 JDK 版本升级到最新版本时jre1.8.0_121,它可以工作。

回答by user674669

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.

在 CentOS 6.6 64 位 linux 上使用 JRE-1.8.0_40 运行 java 应用程序时。

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

在使用 JRE-1.8.0_172 时,异常消失了。

回答by acaruci

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:

我有完全相同的问题。实际上,密钥库文件无效并且与 JDK//JRE 版本无关。我的问题是由 Maven 引起的。我在我的 pom 文件中使用了以下选项:

<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.

过滤中的“真”值弄乱了密钥文件。因此,当 Spring 运行时在我的类路径中可用的密钥文件与我在目录“src/main/resources”下的不完全相同,这导致了无效的密钥库格式异常。当我使用 keytool 进行测试时,我使用的是“资源”文件夹下的那个,因此误导了真正的问题。

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:

解决问题:在您的 pom.xml 文件中,将“过滤”的值更改为“假”。解决该问题的另一种方法是在 application.properties 文件中明确指定密钥库的位置。所以而不是:

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

I used

我用了

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

回答by Zak Aroui

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.

你是如何生成JKS文件的?我尝试了所有建议的解决方案,但没有一个对我有用。尝试读取(在我的代码中)使用 OpenJDK Zulu 11 的 keytool 生成的 JKS 文件时,我遇到了同样的错误。

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.

我通过使用“KeyStore Explorer”工具生成 JKS 文件来解决这个问题,我相信它在内部使用了 oracle JDK。使用该工具,我基本上创建了一个 JKS 文件并将我的可信证书添加到其中。

I hope this helps.

我希望这有帮助。