前言
JDK1.6默认支持 TLS 1.0, SSLv3
直到JDK1.6_121以上才支持TLSv1.2协议(收费)
JDK1.7及以上默认支持TLSv1.1 TLSv1.2
最近的工作需要在原有系统中集成访问另一个系统,在请求时https域名时涉及到一些安全性的问题,涉及到了TLS1.2
相关报错:
*sun.security.validator.ValidatorException:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target*
解决方案
- 升级JDK
-
升级JDK 1.6 到 121 版本之后就会支持 TLS 1.2 。
JDK1.6 121版本是需要收费的!!! -
升级JDK1.6到1.7以上
- 引入外部包
- 需要在项目里引入的包名为 bcprov-jdk15on
- 下载链接: link
- 并且需要根据引入的 jar 包继承实现 SSLSocketFactory 类。
import org.bouncycastle.crypto.tls.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.net.ssl.*;
import javax.security.cert.X509Certificate;
import java.io.*;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.Principal;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateFactory;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
/**
* 实现SSLSocketFactory类,目的使jdk1.6支持TLSv1.2协议
*/
public class TLSSocketConnectionFactory extends SSLSocketFactory {
static {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
public Socket createSocket(Socket socket, final String host, int port,
boolean arg3) throws IOException {
if (socket == null) {
socket = new Socket();
}
if (!socket.isConnected()) {
socket.connect(new InetSocketAddress(host, port));
}
final TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), new SecureRandom());
return _createSSLSocket(host, tlsClientProtocol);
}
public String[] getDefaultCipherSuites() {
return null; }
public String[] getSupportedCipherSuites() {
return null; }
public Socket createSocket<