目录
1、错误代码:
2、AI回答的解决方案
3、自己整理调试成功的方案-采用忽略验证方式
4、使用需要验证的方式-待验证
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:
这个错误通常发生在尝试通过SSL握手与服务器建立安全连接时,但Java无法验证服务器的证书。这可能是由于以下原因:
要解决这个问题,你可以尝试以下方法:
方法一:
如果你有权访问服务器端的证书,你可以将它导入到Java的信任库中。证书通常以.cer
、.crt
或.pem
为扩展名。你可以使用keytool工具(Java的keystore管理工具)来导入证书,命令如下:
ash复制代码
keytool -import -alias server-alias -keystore cacerts -file server-cert.cer |
你需要提供keystore的密码,通常默认密码是changeit
。导入证书后,你应该能够成功地与服务器建立SSL连接。
方法二:
如果你无法访问服务器端的证书,但你知道它是可靠的(例如,它是你的公司内部服务器或你信任的第三方服务),你可以选择忽略SSL握手异常。这样做并不推荐,因为这将使你的连接容易受到中间人攻击,但如果你清楚你正在做什么,你可以这样做:
java复制代码
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); |
|
SSLContext sslContext = SSLContext.getInstance("TLS"); |
|
sslContext.init(null, new TrustManager[]{new X509TrustManager() { |
|
@Override |
|
public X509Certificate[] getAcceptedIssuers() { |
|
return null; |
|
} |
|
@Override |
|
public void checkClientTrusted(X509Certificate[] certs, String authType) { |
|
} |
|
@Override |
|
public void checkServerTrusted(X509Certificate[] certs, String authType) { |
|
} |
|
}}, new SecureRandom()); |
|
connection.setSSLSocketFactory(sslContext.getSocketFactory()); |
这段代码创建了一个自定义的TrustManager,它不验证服务器的证书。请注意,这会使你的连接容易受到中间人攻击,所以只有在你清楚你正在做什么的情况下才使用这种方法。
3.1、情况一:
直接设置参数,在调用wsdl接口前:
import org.apache.axis.AxisProperties;
AxisProperties.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory");
3.2、情况二:
在调用接口前添加如下代码:
ProtocolSocketFactory fcty = new YouSecureProtocolSocketFactory();
类代码如下:
class YouX509TrustManager implements X509TrustManager { /* (non-Javadoc) * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String) */ public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } /* (non-Javadoc) * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String) */ public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } /* (non-Javadoc) * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() */ public X509Certificate[] getAcceptedIssuers() { return null; } } class YouSecureProtocolSocketFactory implements SecureProtocolSocketFactory { //这里添加一个属性,主要目的就是来获取ssl跳过验证 private SSLContext sslContext = null; /** * Constructor for MySecureProtocolSocketFactory. */ public YouSecureProtocolSocketFactory() { } /** * 这个创建一个获取SSLContext的方法,导入MyX509TrustManager进行初始化 * @return */ private SSLContext createEasySSLContext() { try { SSLContext context = SSLContext.getInstance("SSL"); context.init(null, new TrustManager[] { new YouX509TrustManager() }, null); return context; } catch (Exception e) { throw new HttpClientError(e.toString()); } } /** * 判断获取SSLContext * @return */ private SSLContext getSSLContext() { if (this.sslContext == null) { this.sslContext = createEasySSLContext(); } return this.sslContext; } //后面的方法基本上就是带入相关参数就可以了 /* * (non-Javadoc) * * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String, * int, java.net.InetAddress, int) */ public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port,clientHost, clientPort); } /* * (non-Javadoc) * * @see org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket(java.lang.String, * int, java.net.InetAddress, int, * org.apache.commons.httpclient.params.HttpConnectionParams) */ public Socket createSocket(final String host, final int port,final InetAddress localAddress, final int localPort, final HttpConnectionParams params) throws IOException,UnknownHostException, ConnectTimeoutException { if (params == null) { throw new IllegalArgumentException("Parameters may not be null"); } int timeout = params.getConnectionTimeout(); if (timeout == 0) { return createSocket(host, port, localAddress, localPort); } else { return ControllerThreadSocketFactory.createSocket(this, host, port,localAddress, localPort, timeout); } } /* * (non-Javadoc) * * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) */ public Socket createSocket(String host, int port) throws IOException,UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port); } /* * (non-Javadoc) * * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) */ public Socket createSocket(Socket socket, String host, int port,boolean autoClose) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(socket, host,port, autoClose); } }
4.1、使用浏览器打开证书认证网站,导出crt文件-证书链
4.2、在nginx中添加crt-AI解决方案
要在NGINX中添加CRT认证证书,您需要执行以下步骤:
获取CRT认证证书:确保您已经获得了有效的CRT认证证书。证书通常是由证书颁发机构(CA)签发的,并且用于验证网站的身份。
打开NGINX配置文件:在NGINX的主配置文件中,找到http
块。该块通常位于nginx.conf
文件中。
添加ssl_certificate
指令:在http
块中,找到您要配置的服务器块(通常使用server
块标识)。在该服务器块中,添加以下指令以指定CRT认证证书的位置:
bash复制代码
ssl_certificate /path/to/crt_file.crt; |
将/path/to/crt_file.crt
替换为您实际CRT认证证书文件的路径。
4. 添加ssl_certificate_key
指令:同样在服务器块中,添加以下指令以指定与CRT认证证书关联的密钥文件:
bash复制代码
ssl_certificate_key /path/to/private_key.key; |
将/path/to/private_key.key
替换为您实际的私钥文件的路径。
5. 保存并关闭配置文件:保存对NGINX配置文件的更改,并关闭文件。
检查配置文件语法:运行以下命令来验证NGINX配置文件的语法是否正确:
复制代码
nginx -t |
如果没有显示任何错误消息,则表示配置文件语法正确。
7. 重新加载NGINX配置:如果配置文件的语法正确,使用以下命令重新加载NGINX以使更改生效:
复制代码
nginx -s reload |
这将重新加载NGINX配置并应用新的CRT认证证书。
完成上述步骤后,NGINX将使用您提供的CRT认证证书对客户端进行身份验证。请确保替换实际的文件路径和密钥文件路径,并确保NGINX具有适当的读取权限来访问这些文件。
4.3、tomcat中添加crt
要在Tomcat中添加CRT认证证书,您可以按照以下步骤进行操作:
conf
文件夹,并打开该文件夹。server.xml
文件:在conf
文件夹中,找到server.xml
文件,这是Tomcat的主要配置文件。
元素:在server.xml
文件中,查找
元素。该元素用于配置Tomcat的网络连接参数。sslProtocol
属性:在
元素中,添加sslProtocol
属性,并设置其值为"TLS"。这告诉Tomcat使用TLS协议来处理SSL/TLS连接。SSLEnabled
属性:在
元素中,添加SSLEnabled
属性,并设置其值为"true"。这启用Tomcat的SSL/TLS功能。keystoreFile
和keystorePass
属性:在
元素中,添加keystoreFile
属性,并设置其值为包含您的CRT认证证书的密钥库文件的路径。然后,添加keystorePass
属性,并设置其值为密钥库文件的密码。server.xml
文件的更改,并关闭该文件。完成上述步骤后,Tomcat将使用您提供的CRT认证证书对客户端进行身份验证。请确保替换实际的文件路径和密码,并确保Tomcat具有适当的读取权限来访问这些文件。