簡體   English   中英

SSL Java java.io.IOException:密鑰庫格式無效

[英]SSL Java java.io.IOException: Invalid keystore format

我正在使用 SSLServerSocket 和 java.ssl package 中的 SSLServerSocket 和其他類在 java 中測試 SSL。當我運行以下代碼時,出現異常 java.88686853.8456 我的代碼:

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

文件 key.txt:1268312345812304612348712634283427346 我猜我應該在 key.txt 文件中放一些別的東西,但我不知道放什么。 可能是一個 searilized object。

編輯:客戶代碼:

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

我有完全相同的問題。 實際上,keystore 文件是無效的,並且與 JDK//JRE 版本無關。 我的問題是由 Maven 引起的。 我在我的 pom 文件中使用了以下選項:

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

過濾中的“真”值與密鑰文件混淆。 因此,當 Spring 運行時,在我的類路徑中可用的密鑰文件與我在目錄“src/main/resources”下的密鑰文件不完全相同,這導致了 Invalid Keystore Format 異常。 當我使用 keytool 進行測試時,我使用的是“資源”文件夾下的那個,所以這會誤導真正的問題。

解決問題:在您的 pom.xml 文件中,將“filtering”的值更改為“false”。 解決此問題的另一種方法是在 application.properties 文件中明確指定密鑰庫的位置。 所以而不是:

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

我用了

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

您的文件無效。 您必須導入 JKS 密鑰庫文件而不是 txt 文件。 您必須使用keytool創建您的密鑰庫文件,然后導入此文件。

使用以下代碼load keystore時,我遇到了同樣的問題:

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

原來是JDK問題,它不適用於jre1.8.0_25 當我將 JDK 版本升級到最新的jre1.8.0_121時,它可以工作。

對於我的情況,我使用了不同版本的 keytool 和 java,一旦我切換到相同的 jdk,它們就得到了修復。

我看到了這個異常:

無效的密鑰庫格式

在 CentOS 6.6 64 位 Linux 上使用 JRE-1.8.0_40 運行 java 應用程序時。

在使用 JRE-1.8.0_172 時,異常消失了。

您是如何生成 JKS 文件的? 我嘗試了所有建議的解決方案,但沒有一個對我有用。 嘗試讀取(在我的代碼中)使用 OpenJDK Zulu 11 的 keytool 生成的 JKS 文件時,我遇到了同樣的錯誤。

我通過使用“KeyStore Explorer”工具生成 JKS 文件來解決此問題,我相信該工具在內部使用 oracle JDK。 使用該工具,我基本上創建了一個 JKS 文件並將我的受信任證書添加到其中。

我希望這有幫助。

即使我使用的是有效的 .jks 文件,我最近也遇到了同樣的問題......以前的代碼可以正常工作,但突然它開始給出“無效的密鑰庫格式”

前面給出的將 pom.xml 資源過濾值設置為“false”的答案也對我有用,例如,

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

mac用戶

System Preferences -> JAVA -> JAVA Control Panel -> Update tab中更新JDK

從 java 版本“1.8.0_231”“1.8.0_333”修復了這個問題

如果你使用 openjdk:
使用 openjdk 版本“11.0.17”或更新版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM