如何在Java中使用TLSV1或SSLV3进行第一次握手(Client Hello)?

当我执行以下代码时,为什么第一次握手是SSLv2,而不是TLSv1或SSLv3?

如何在Java中使用TLSV1或SSLV3进行首次握手?

String host = "www.google.com"; String url = "/adsense/?sourceid=aso&subid=ZH_CN-ET-AS-ADSBY6&medium=link&hl=zh_CN"; SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom()); SSLContext.setDefault(ctx); SSLSocketFactory factory = ctx.getSocketFactory(); Socket socket = factory.createSocket(host, 443); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out.write("GET " + url + " HTTP/1.0"); out.flush(); out.close(); in.close(); 

对于TLSv1:使用启动客户端jvm

 -Dhttps.protocols="TLSv1" 

或使用

 System.setProperty("https.protocols", "TLSv1"); 

为我解决了这个问题。

使用SSLSocket

 SSLSocket socket = factory.createSocket(host, 443); String[] newProtocols = {"TLSv1"}; socket.setEnabledProtocols(newProtocols); 

你使用的是哪个版本的java? 另外你怎么说它使用SSLv2? 默认情况下,java 1.6将使用TLSv1。 这里有一个问题,如果您启用debug ssl,您可能会看到正在使用SSLv2Hello格式,但如果您仔细查看,记录层内的’protocol vesion’将是TLSv1(SSLv2格式下的1.e版本信息包装器)。 使用wireshark的TCP级别数据包捕获分析应该确认这一点。 如果要以TLSv1格式启动,只需设置https.protocols = TLSv1(这可能会影响所有传出的ssl调用)或在上面的特定套接字上设置。 请注意,即使你有五个逗号分隔列表(如https.protocols = SSLv3,TLSv1),它也会以TLSv1开头。