(1)直接指定SSLSocket,只影响这一个连接。
SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(hosturl, port); sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
数组,可以写多个协议。
(2)指定SSLSocketFactory,共用这个工厂,则影响多个连接。
import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom;
import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory;
public class SSLPoke {
public SSLPoke() { }
public static void main(String args[]) {
try { SSLContext sc = SSLContext.getInstance("TLSv1.2"); sc.init((KeyManager[])null, null, new SecureRandom()); SSLSocketFactory sslsocketfactory = sc.getSocketFactory(); //SSLSocketFactory sslsocketfactory = (SSLSocketFactory)SSLSocketFactory.getDefault(); SSLSocket sslsocket = (SSLSocket)sslsocketfactory.createSocket("cloud.xxx.com", 443); InputStream inputstream = sslsocket.getInputStream(); OutputStream outputstream = sslsocket.getOutputStream(); outputstream.write(1); for(; inputstream.available() > 0; System.out.print(inputstream.read())); System.out.println("Successfully connected"); System.exit(0); } catch(SSLHandshakeException sslhandshakeexception) { if(sslhandshakeexception.getCause() != null) sslhandshakeexception.getCause().printStackTrace(); else sslhandshakeexception.printStackTrace(); } catch(Exception exception) { exception.printStackTrace(); } System.exit(1); } }
貌似只能指定一个协议版本。
(3)结合HttpsURLConnection使用
URL url = new URL("https://cloud.xxx.com/xxx/api/sync/v1/yy/json"); HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); conn.setSSLSocketFactory(sslsocketfactory); InputStream inputstream = conn.getInputStream();
(4)使用Property,影响整个JVM,慎用!! System.setProperty("https.protocols","TLSv1.2"); 可以写多个协议,逗号分隔,不知道用哪个版本是如何决定的。
(5)使用-D参数,可以写多个,逗号分隔,全局,慎用 -Dhttps.protocols=TLSv1.2 好使,貌似只能控制HttpsURLConnection时tls的版本。
注意:这个参数影响不到SSLSocket, 如果用sslsocketfactory指定了TLSv1.1,那么sslsocketfactory.createSocket得到的SSLSocket就是TLSv1.1,即使-Dhttps.protocols=TLSv1.2
注意:这个参数影响HttpsURLConnection,-D参数指定啥版本就是啥版本,不管你里面sslsocketfactory怎么写的。
-Djdk.tls.client.protocols=TLSv1.2 不好使,jdk版本>=1.7.0_95才可用。 我是79版本,所以不行。 它是底层控制tls版本,更厉害一点?
|