【问题标题】:Java SSL cacerts working only on local machineJava SSL cacerts 仅在本地机器上工作
【发布时间】:2019-10-20 16:13:40
【问题描述】:

我的程序中有一段代码设置了一个套接字连接,然后写入远程服务器。

        //Get Socket, set timeout, and initialize I/O streams
        SSLSocket sock = null;
        try {
            InetAddress host = InetAddress.getByName("212.32.251.215");
            int port = 55540;
            SSLSocketFactory sslsocketfactory = (SSLSocketFactory) 
            SSLSocketFactory.getDefault();
            sock = (SSLSocket) sslsocketfactory.createSocket(host, port);
        } catch (Exception e) {
             e.printStackTrace();
        } 
        sock.setSoTimeout(100000);
        OutputStream out = sock.getOutputStream();
        BufferedInputStream in = new BufferedInputStream(sock.getInputStream());

        //Get Message (Compress and Encrypt)
        byte[] msg = buildMsg();

        //Send message to Server
        out.write(msg);
        out.flush();

在我的本地计算机上,一切运行顺利,但在我的云服务器上,我遇到了一个熟悉的错误 - 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

我已确保证书在带有keytool -list -v -keystore /etc/pki/java/cacerts -alias myalias 的 cacerts 中。我还检查了这个 cacerts 是我的 java 应用程序的默认信任库,System.getProperty("javax.net.ssl.trustStore"); 返回/etc/pki/java。话虽如此,我什至尝试过System.setProperty("javax.net.ssl.trustStore", "/etc/pki/java/cacerts");,正如有人说 Tomcat 忽略了他们的默认 trustStore 所建议的那样。另外,是的,这是我服务器中所有 jre 版本的 cacerts 位置,每个 jre 都有一个 cacerts 但它是指向这个规范位置的符号链接。

此时我不知道为什么我仍然会收到此错误;任何建议或解决方案表示赞赏。谢谢。

【问题讨论】:

    标签: java ssl-certificate


    【解决方案1】:

    我最终通过显式创建一个 trustStore 来解决这个问题,而不是依赖 java 来找到它。

            KeyStore trustStore = KeyStore.getInstance("JKS");
            trustStore.load(new FileInputStream(mypath), password.toCharArray());
    
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
            tmf.init(trustStore);
    
            SSLContext sslcontext = SSLContext.getInstance("SSLv3");
            sslcontext.init(null, tmf.getTrustManagers(), null);
    
            SSLSocketFactory sslsocketfactory = sslcontext.getSocketFactory();
    
            InetAddress host = InetAddress.getByName("212.32.251.215");
            int port = 55540;
    
            sslsocket = (SSLSocket) sslsocketfactory.createSocket(host, port);
    

    【讨论】:

    • “依赖Java找到它”是什么意思? Java没有魔法。如果您的应用程序在这样的环境中或在您的应用程序代码本身中运行,则信任库要么在 JVM 级别(cacerts)上定义,要么在应用程序服务器(例如 Tomcat)内定义。您也可以使用环境变量来设置信任库...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    相关资源
    最近更新 更多