如何在eclipse中使用TLS1.2协议获取简单的Java客户端连接到服务器

问题描述:

我尝试了几种使用httpclient,urlconnection等无效访问休息服务的常用方法。如何在eclipse中使用TLS1.2协议获取简单的Java客户端连接到服务器

我已经阅读了无数堆栈溢出文章如何做到这一点,没有任何工程在我的eclipse mobilefirst/RSA环境。我正在使用mobilefirst 7.1.1和RSA 9.1.1运行jdk 1.7。

从我读到的,你必须设置SSLContext与tls1.2服务器交谈......因为相同的代码在其他服务器上工作正常。我所看到的只有一种方法可以让你设置SSLContext,这与ClientHTTPBuilder一致。

所以这里有几个例子:

此示例为这个网址...但是,使用tls1.2

URL url = new URL("https://wikipedia.org"); 
     URLConnection urlConnection = url.openConnection(); 
     InputStream in = urlConnection.getInputStream(); 
     str = getStringByBufferedReader(in); 

第二个例子不是一个:

SSLContext context = SSLContext.getInstance("TLS"); 
    context.init(null, null, null); 
HttpClientBuilder clientBuilder = HttpClientBuilder.create().setSslcontext(context); 
HttpGet request = new HttpGet(baseURL); 
request.addHeader("Authorization", basicAuthorization); 
request.addHeader("Accept", "text/plain"); 
CloseableHttpClient httpClient = clientBuilder.build(); 
CloseableHttpResponse httpResponse = httpClient.execute(request); 

两种连接类型都会出现以下错误:

Exception in Test method = javax.net.ssl.SSLException: Received fatal alert: protocol_version 

我也导入了证书。我也试过jdk 1.8无济于事。

JRE7中的TLS解析为TLSv1。明确设置协议TLSv1.2工作:

SSLContext context = SSLContext.getInstance("TLSv1.2"); 

否则与HttpClientBuilder你的例子是OK。

编辑:

如果要禁用主机名检查(这是在生产系统坏主意):

随着Apache httpclient < 4.3:

package hello; 

import java.net.URI; 

import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.CloseableHttpResponse; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.conn.scheme.Scheme; 
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 
import org.apache.http.conn.ssl.SSLSocketFactory; 
import org.apache.http.impl.client.DefaultHttpClient; 


public class client { 

    public static void main(String args[]) throws Exception { 

//  System.setProperty("javax.net.debug", "ssl:handshake:verbose"); 

     SSLSocketFactory socketFactory = null ; 

     // Set benevolent host name verifier    
     socketFactory = new SSLSocketFactory("TLS" , null /* Keystore*/ , 
       null /* keystore passwd */ ,null /* trusts store */ , null , 
       SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) ; 

     Scheme sch = new Scheme("https", 443, socketFactory); 
     DefaultHttpClient httpClient = new DefaultHttpClient() ;   
     httpClient.getConnectionManager().getSchemeRegistry().register(sch);   

     HttpGet request = new HttpGet(new URI("https://www.wikipedia.org/")); 
//  request.addHeader("Authorization", basicAuthorization); 
//  request.addHeader("Accept", "text/plain"); 
     CloseableHttpResponse httpResponse = httpClient.execute(request); 
     System.out.println(httpResponse.getStatusLine()); 

     httpClient.close(); 
    } 
} 

随着Apache httpclient> = 4.3:

package hello; 

import java.net.URI; 
import java.util.Arrays; 

import javax.net.ssl.HostnameVerifier; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLParameters; 
import javax.net.ssl.SSLSession; 
import javax.net.ssl.SSLSocket; 
import javax.net.ssl.SSLSocketFactory; 

import org.apache.http.client.methods.CloseableHttpResponse; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClientBuilder; 

import sun.security.ssl.SSLSocketFactoryImpl; 

public class client { 

    public static void main(String args[]) throws Exception { 

//  System.setProperty("javax.net.debug", "ssl:handshake:verbose"); 

     SSLContext context = SSLContext.getInstance("TLSv1.2"); 
     context.init(null, null, null); 

     SSLConnectionSocketFactory sslCF = new SSLConnectionSocketFactory(context, new HostnameVerifier() { 
      @Override 
      public boolean verify(String hostname, SSLSession session) { 
       // or add your own test here 
       return true; 
      } 
     }); 

     CloseableHttpClient httpClient = HttpClientBuilder 
       .create() 
       .setSSLSocketFactory(sslCF) 
       .build(); 

     HttpGet request = new HttpGet(new URI("https://www.wikipedia.org/")); 
//  request.addHeader("Authorization", basicAuthorization); 
//  request.addHeader("Accept", "text/plain"); 
     CloseableHttpResponse httpResponse = httpClient.execute(request); 
     System.out.println(httpResponse.getStatusLine());   
    } 
} 
+0

我没有你的建议,现在收到此错误: – Tim

+0

javax.net.ssl.SSLProtocolException:握手警报:unrecognized_name – Tim

+0

我觉得现在我们正在谈论真正的问题......这可能是证书问题吗?我从服务器导入的证书是自签名证书......不确定在TLS 1.2中是否允许这样做。通过添加--insecure选项,我可以通过curl工作。它也适用于Chrome和Firefox的各种其他客户端。 – Tim

我能够在主类一行修复它:

System.setProperty("https.protocols", "SSLv3,TLSv1,TLSv1.1,TLSv1.2");