0导言
工作中遇到,系统服务内部调用增加对TLSv1.2协议的支持,因此做了兼容测试
1测试结果
如表,TLS有一个内置机制来协商是使用那个版本的协议,客户端发送一个高版本协议,其中包含低版本协议,如果服务器不支持此高版本协议,他们将协议使用低版本协议。
2测试环境
jdk版本:
1.8,默认支持:[SSLv2Hello,SSLv3,TLSv1,TLS1.1,TLS1.2]
浏览器:
谷歌, 其版本80.0.3987.132(正式版本)(64位) 31以上就默认支持TLSv1.2
客户端:
httpClient 3.0
服务器
Tomcat7 7以上版本支持TLSv1.2
3测试变量控制
变量1:tomcat服务端配置
准备:
1、使用jdk的keytools创建密钥放入tomcat中
2、tomcat配置https,添加443端口,配置密钥信息
通过修改tomcat7的配置文件,D:\Developtools\apache-tomcat-7.0.107\conf\server.xml
原https配置:
配置当前服务器只支持SSL\TLS协议的版本:
<Connector port=“443” protocol=“org.apache.coyote.http11.Http11Protocol”
maxThreads=“150” SSLEnabled=“true” scheme=“https” secure=“true”
clientAuth=“false” sslProtocol=“TLS” keystoreFIle=“D:\tomcat.keystore” keystorePass=“123456” sslEnabledProtocols="xxx" />
分别配置:
1. sslEnabledProtocols="TLSv1" (TLSv1等于SSLv3) 此配置后服务器端支持1.0
2. sslEnabledProtocols="TLSv1.1" 此配置后服务器端支持1.1
3. sslEnabledProtocols="TLSv1.2" 此配置后服务器端支持1.2
变量2:httpClient客户端配置
修改MySecureProtocolSocketFactory类中sslcontext=SSLContext.getInstance(“xxx”)
分别配置:
1. sslcontext=SSLContext.getInstance("TLSv1.2")
2. sslcontext=SSLContext.getInstance("TLSv1.1")
3. sslcontext=SSLContext.getInstance("TLSv1")
4. sslcontext=SSLContext.getInstance("SSLv3")
5. sslcontext=SSLContext.getInstance("SSL")
注意1 客户端配置高版本会兼容低版本(ps:只能拍照,懂得懂)
注意2
那么如何测试,当前客户端发送的默认那种版本的协议呢?
抓包工具:Fiddler
代码如下:
HttpsProxyGet类的关键点是设置抓包工具的代理
package com.java;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
public class HttpsProxyGet {
public static void main(String[] args) throws Exception {
SSLClient httpclient = new SSLClient();
// 访问的目标站点,端口和协议
HttpHost targetHost = new HttpHost("www.baidu.com", 443, "https");
// 代理的设置
HttpHost proxy = new HttpHost("localhost", 8888);
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
// 目标地址
HttpGet httpget = new HttpGet("/s");
System.out.println("目标: " + targetHost);
System.out.println("请求: " + httpget.getRequestLine());
System.out.println("代理: " + proxy);
// 执行
HttpResponse response = httpclient.execute(targetHost, httpget);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
// 显示结果
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
if (entity != null) {
entity.consumeContent();
}
}
}
package com.java;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
/**
* 用于进行Https请求的HttpClient
* @ClassName: SSLClient
* @Description: TODO
* @author Devin <xxx>
*
*/
public class SSLClient extends DefaultHttpClient {
public SSLClient() throws Exception{
super();
SSLContext ctx = SSLContext.getInstance("TLSv1");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = this.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));
}
}
抓包结果: 与 SSLContext ctx = SSLContext.getInstance(“TLSv1”)中配置一致,默认高版本
4测试思路及过程
思路:
1、使用谷歌浏览器与提供端服务器建立连接访问,可验证到当前服务器协议版本。
调用谷歌浏览器,按F12查看:
2、消费者端发起服务调用,即使用httpClient发起https请求,查看服务调用情况。
变量1和变量2交叉改变,进行测试
测试结果共15种,在文章头表中。
5结语
文章梳理可能有点乱,对这块还是半只半知半解。
-----重言