在 apache tomcat 中部署时证书 (HTTPS) 无效,但在 Intellij(本地)中运行良好

Invalid Certificate (HTTPS) while deploy in apache tomcat but work perfectly in Intelij (local)

我有使用 https 发送数据的应用程序,为此,我实施了从目标网站获取的 https 证书。 certificate destination website

我从网站上获取了 2 个证书(GeoTrust 和 Digicert)并使用密钥库资源管理器将其保存到 jks 文件中,看起来像 jks file

并将其上传服务器到特定目录

在java应用程序中,我添加了一些代码来读取特定路径中的jks文件并从应用程序实施证书

import javax.net.ssl.HttpsURLConnection;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SSLUtils {


    @Value("${ssl.keyStore.file}")
    private String sslKeyStoreFile;

    @Value("${ssl.keyStore.pass}")
    private String sslKeyStorePass;

    @Value("${ssl.trustStore.file}")
    private String sslTrustStoreFile;

    @Value("${ssl.trustStore.pass}")
    private String sslTrustStorePass;

    @Value("${ssl.host}")
    private String sslHost;


    /**
     * Setting configuration for SSL certificate
     *
     */

    @Bean
    public void setKeySSL(){
        HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> hostname.equals(sslHost));
        System.setProperty("javax.net.ssl.trustStore", sslTrustStoreFile);
        System.setProperty("javax.net.ssl.trustStorePassword", sslTrustStorePass);
        System.setProperty("javax.net.ssl.keyStore", sslKeyStoreFile);
        System.setProperty("javax.net.ssl.keyStorePassword", sslKeyStorePass);
    }

}

ssl 的属性

#ssl client config
ssl.keyStore.file=/opt/ssl/keystore.jks
ssl.keyStore.pass=admin
ssl.trustStore.file=/opt/ssl/keystore.jks
ssl.trustStore.pass=admin
ssl.host=https://devapi.***********.co.id

部署到 apache tomcat 9.0.37 后,出现错误 “PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径;嵌套异常是 javax.net.ssl.SSLHandshakeException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求的有效证书路径目标”。

但是当我 运行 在本地使用 intelijj 应用程序时,应用程序 运行 运行良好并得到目的地的响应,与 运行 应用程序 war 文件形式的结果相同使用命令 java -jar 这意味着实现 ssl 运行 的代码也很好。

我很确定,ssl文件的路径没有问题。 我假设这个问题的原因是 jks 文件无法在 tomcat 中读取,而不是无效的证书(因为在本地,我使用相同的证书及其有效)

问题是:这怎么可能发生?

仅供参考:我还有另一个微服务,它使用相同的代码来实现 ssl 并且它在同一个 apache 中工作正常 tomcat。

一些我已经完成但不起作用的解决方案:

  1. 运行 apache tomcat 在 root 模式下与 ssl 文件中目录和文件的所有者相同 (opt/ssl/)
  2. 导入证书到jvm证书
  3. 将证书导入 jvm 证书并在代码中读取 /usr/java/jdk1.8.0_261/jre/lib/security/cacerts
  4. 中的 cacerts 文件

这个 post 有更新吗?

我假设这个问题的原因是你没有捆绑证书权利或每个证书的别名

终于,在与这个问题纠缠了一周之后,我终于解决了这个问题。 问题是密钥库服务器(目标服务器)只包含没有根 CA 证书和中间证书的服务器证书。 这就是为什么在握手过程中建立连接失败的原因。因为在建立连接时,服务器会发送所有证书(链证书)。

请观看关于 SSL 过程的讲座: SSL and HTTPS Lecture

求解步骤:

  1. 在客户端服务器中,从服务器获取证书

https://github.com/escline/InstallCert

为此,请使用 InstallCert.java 和 运行

java -Djavax.net.debug=ssl:handshake InstallCert host:port

注意:如果所有 chain-certificate 不完整(没有 CA 证书和中间件),请联系管理员服务器将所有证书添加到服务器密钥库中。

  1. 在客户端服务器中,检查刚刚通过 InstallCert.java
  2. 建立的与 trustore 的连接

https://github.com/gebi/sslpoke

为此,请使用 SSLPoke.java 和 运行

java -Djavax.net.debug=ssl -Djavax.net.ssl.trustStore=jssecacerts SSLPoke host port

注意:如果连接成功,则可以使用该 trustore。

如果不能解决您的问题,您可以通过在startup.sh

中添加命令来调试您的tomcat

https://medium.com/@anuruddha.thennakoon/enable-ssl-debug-logs-in-tomcat-f9d7e0d1fd67