在 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。
一些我已经完成但不起作用的解决方案:
- 运行 apache tomcat 在 root 模式下与 ssl 文件中目录和文件的所有者相同 (opt/ssl/)
- 导入证书到jvm证书
- 将证书导入 jvm 证书并在代码中读取 /usr/java/jdk1.8.0_261/jre/lib/security/cacerts
中的 cacerts 文件
这个 post 有更新吗?
我假设这个问题的原因是你没有捆绑证书权利或每个证书的别名
终于,在与这个问题纠缠了一周之后,我终于解决了这个问题。
问题是密钥库服务器(目标服务器)只包含没有根 CA 证书和中间证书的服务器证书。
这就是为什么在握手过程中建立连接失败的原因。因为在建立连接时,服务器会发送所有证书(链证书)。
请观看关于 SSL 过程的讲座:
SSL and HTTPS Lecture
求解步骤:
- 在客户端服务器中,从服务器获取证书
为此,请使用 InstallCert.java 和 运行
java -Djavax.net.debug=ssl:handshake InstallCert host:port
注意:如果所有 chain-certificate 不完整(没有 CA 证书和中间件),请联系管理员服务器将所有证书添加到服务器密钥库中。
- 在客户端服务器中,检查刚刚通过 InstallCert.java
建立的与 trustore 的连接
为此,请使用 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
我有使用 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。
一些我已经完成但不起作用的解决方案:
- 运行 apache tomcat 在 root 模式下与 ssl 文件中目录和文件的所有者相同 (opt/ssl/)
- 导入证书到jvm证书
- 将证书导入 jvm 证书并在代码中读取 /usr/java/jdk1.8.0_261/jre/lib/security/cacerts 中的 cacerts 文件
这个 post 有更新吗?
我假设这个问题的原因是你没有捆绑证书权利或每个证书的别名
终于,在与这个问题纠缠了一周之后,我终于解决了这个问题。 问题是密钥库服务器(目标服务器)只包含没有根 CA 证书和中间证书的服务器证书。 这就是为什么在握手过程中建立连接失败的原因。因为在建立连接时,服务器会发送所有证书(链证书)。
请观看关于 SSL 过程的讲座: SSL and HTTPS Lecture
求解步骤:
- 在客户端服务器中,从服务器获取证书
为此,请使用 InstallCert.java 和 运行
java -Djavax.net.debug=ssl:handshake InstallCert host:port
注意:如果所有 chain-certificate 不完整(没有 CA 证书和中间件),请联系管理员服务器将所有证书添加到服务器密钥库中。
- 在客户端服务器中,检查刚刚通过 InstallCert.java 建立的与 trustore 的连接
为此,请使用 SSLPoke.java 和 运行
java -Djavax.net.debug=ssl -Djavax.net.ssl.trustStore=jssecacerts SSLPoke host port
注意:如果连接成功,则可以使用该 trustore。
如果不能解决您的问题,您可以通过在startup.sh
中添加命令来调试您的tomcathttps://medium.com/@anuruddha.thennakoon/enable-ssl-debug-logs-in-tomcat-f9d7e0d1fd67