【问题标题】:Java SSL connection error - Invalid keystore formatJava SSL 连接错误 - 无效的密钥库格式
【发布时间】:2016-05-08 20:17:36
【问题描述】:

我正在创建一个服务器和客户端一体化聊天应用程序,并且我正在尝试切换到 SSL 连接。我创建了一个 keystore.jks 和一个证书文件 (.cer) 但现在当程序尝试建立连接时,代理客户端会抛出:

原因:java.io.IOException: Invalid keystore format

代码如下:

System.setProperty("javax.net.ssl.keyStore", "certificates/keystore.jks");
System.setProperty("javax.net.ssl.trustStore", "certificates/certificate.cer");
System.setProperty("javax.net.ssl.keyStorePassword", "password");

if (this.role == ConnectionRole.SERVER) {
    connectingAlert.getJFrame().setVisible(true);
    setupServer();
    do {
        Thread.sleep(10);
    } while (socket == null);
}

if (this.role == ConnectionRole.CLIENT) {
    connectingAlert.getJFrame().setVisible(true);
    setupClient(targetIP);
}

private void setupServer() throws IOException {
    SSLServerSocketFactory sslSrvFact = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
    serverSocket = (SSLServerSocket) sslSrvFact.createServerSocket(8080, 1);
    socket = (SSLSocket) serverSocket.accept();
    setupStreams();
}

private void setupClient(String IPAddress) throws IOException {
    SSLSocketFactory sslFact = (SSLSocketFactory) SSLSocketFactory.getDefault();
    socket = (SSLSocket) sslFact.createSocket("localhost", 8080);
    setupStreams();
}

private void setupStreams() throws IOException {
    dataOut = new ObjectOutputStream(socket.getOutputStream());
    dataIn = new ObjectInputStream(socket.getInputStream());
    chatInterface = ChatInterface.getInstance();
}

【问题讨论】:

  • 我对此完全陌生,只是想按照教程进行操作。添加 javax.net.ssl.trustStore 意味着我不再收到错误:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
  • 由于帖子中使用的代码版本(带有无效格式错误)我删除了System.setProperty("javax.net.ssl.trustStore", "certificates/certificate.cer");这一行,以向您展示我遇到的错误。在我添加线路后。使用与帖子中相同的代码,我转到链接的“可能重复”问题,并使用了顶部评论中的确切代码行。然后我发布了关于我得到的 keytool 错误的评论。今天晚些时候,我将重新尝试创建密钥库和证书,并评论我用来执行此操作的命令。
  • 我没有。听起来这可能是我的问题。所以我应该为服务器创建一个,为客户端创建一个。所以我认为我必须使用服务器和客户端密钥存储中的自签名证书?
  • 好的。我设法完成了。我从一开始就使用 [To Use keytool to Create a Server Certificate] (docs.oracle.com/cd/E19798-01/821-1841/gjrgy/index.html)。非常感谢您的耐心和回答@dur。

标签: java ssl keystore truststore jsse


【解决方案1】:
System.setProperty("javax.net.ssl.trustStore", "certificates/certificate.cer");

问题就在这里。 .cer 文件不是信任库。您需要通过带有-trustcacerts 选项的keytool 将其导入真正的Java 信任库。

但是根本不清楚您为什么要使用信任库。您是否希望拥有自签名证书的同行将其发送给您?大多数时候你应该只使用Java自带的truststore,根本不要设置javax.net.ssl.trustStore

【讨论】:

  • 你能推荐我应该使用什么吗?在网上寻找解决方案,这似乎是我应该使用的。这是一个程序中的服务器/客户端(取决于用户输入),我应该使用什么来建立 SSL 连接?
  • BUT it isn't clear why you're using a truststore at all., you should just use the truststore that comes with Java。我在问如何做到这一点。仅设置 javax.net.ssl.keyStorejavax.net.ssl.keyStorePasword 会在客户端出现 PKIX path building failed 错误,在服务器端设置 Received fatal alert: certificate_unknown
  • 好吧,假设您回答了我提出的问题。 “您是否希望拥有自签名证书的同行将其发送给您?”如果是这样,为什么?您应该使用 CA 签名的证书。但是,如果这就是您正在做的事情,那就是您需要自定义信任库的原因。 'unknown_certificate` 问题完全是一个单独的问题:服务器不信任 your 证书。
猜你喜欢
  • 2014-11-22
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多