SSl:Secure Sockets Layer 安全套接层

TLS:Transport Layer Security传输层安全

是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。(见百度)

场景描述:将公司请求第三方公司的接口协议由http改成https后,出现了请求套接字异常的情况,第三方公司也收不到具体的请求,具体异常如下,

javax.ws.rs.ProcessingException: java.net.SocketException: Connection reset
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:287)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:252)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:411)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:311)
at com.baoxian.payment.UnionPayPayment.request(UnionPayPayment.java:323)
...

Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:209)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1513)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:394)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
... 66 more

实现http协议的代码为:

 import java.security.SecureRandom;
import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; public class ClientUtil {
private static Log log = LogFactory.getLog(ClientUtil.class);
private static SSLContext sslContext = null;
private static HostnameVerifier hv = null;
public static Client sslClient = null;
public static Client client = null;
static{
client = ClientBuilder.newClient();
try {
sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
} public void checkClientTrusted(X509Certificate[] certs, String authType) {
} public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} }, new SecureRandom());
} catch (Exception e) {
log.error("SSL失败", e);
}
hv = new HostnameVerifier() {
public boolean verify( String arg0, SSLSession arg1 ) { return true; }
};
sslClient = ClientBuilder.newBuilder().hostnameVerifier(hv).sslContext(sslContext).build();
}
}

调用ClientUtil类的代码

         url = url + "?data=" + URLEncoder.encode(jsonObject.toJSONString(), "UTF-8");
log.info("银联请求: type: " + transType + ", URL:" + url); Response response = ClientUtil.client.
.target(url)
.request()
.get();

这里的代码写死了只能用SSLv3安全协议,一运行的时候就报连接错误。可是,同样的请求放到google浏览器上请求就可以通过。

把请求复制到google浏览器请求栏,按F12,点击enter键,查看Security菜单栏输出的网页内容,发现这个请求接受TLS1.2安全协议

为了不影响其它类使用SSL协议,对这个类进行重写。重写后类,新增了获取制定安全协议的方法,支持指定安全协议的请求。
 import java.security.SecureRandom;
import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; public class ClientUtil {
private static Log log = LogFactory.getLog(ClientUtil.class);
private static SSLContext sslContext = null;
private static HostnameVerifier hv = null;
public static Client sslClient = null;
public static Client client = null;
private static TrustManager simpleTrust=null;
static{
client = ClientBuilder.newClient();
try {
sslContext = SSLContext.getInstance("SSLv3");
simpleTrust=new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
} public void checkClientTrusted(X509Certificate[] certs, String authType) {
} public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
};
sslContext.init(null, new TrustManager[] { simpleTrust}, new SecureRandom());
} catch (Exception e) {
log.error("SSL失败", e);
}
hv = new HostnameVerifier() {
public boolean verify( String arg0, SSLSession arg1 ) { return true; }
};
sslClient = ClientBuilder.newBuilder().hostnameVerifier(hv).sslContext(sslContext).build();
} public static Client getSslClient(String protocol)
{
try {
SSLContext sslContextTmp= SSLContext.getInstance(protocol);
sslContextTmp.init(null, new TrustManager[] { simpleTrust}, new SecureRandom());
return ClientBuilder.newBuilder().hostnameVerifier(hv).sslContext(sslContextTmp).build();
}
catch (Exception ex)
{
return ClientBuilder.newBuilder().hostnameVerifier(hv).sslContext(sslContext).build();
}
}
}

改正后的调用方法

         url = url + "?data=" + URLEncoder.encode(jsonObject.toJSONString(), "UTF-8");

         Response response = ClientUtil.getSslClient("TLSv1.2")
.target(url)
.request()
.get();

说明:不同第三方公司支持https协议的时候可以用不同安全协议,对于不同的情况要予以考虑。

												

最新文章

  1. Android中使用AsyncTask实现文件下载以及进度更新提示
  2. Block常用方法以及注意事项
  3. android 打包失败
  4. viewPage
  5. 实现读入一个彩色视频文件并以灰度格式输出这个视频文件,学习opencv例2-10
  6. Windows Phone 8.1 页面导航
  7. Android_Intent_passValue(4)
  8. ideadpad-安装win7
  9. Java发送邮件的简单实现
  10. 【转】c/c++各种字符、字符串类型转换
  11. Android开发_关于如何屏蔽Home键
  12. 【IE】浏览器模式与文档模式 及其开发中处理方式
  13. java mqtt
  14. linux的基本操作(磁盘管理)
  15. common lisp 里的几个操作符(2)
  16. Altera 在线资源使用
  17. linux设置服务器时间同步
  18. Charles抓取https包
  19. hdu 5753 Permutation Bo 水题
  20. spring 核心思想:AOP 理解

热门文章

  1. <c:if>判断两个<c:forEach>里的数据是否相等
  2. WordPress 4.3.1正式发布 修复了3个安全问题
  3. Java中System.getProperty()的参数
  4. struts2对ognl表达式的使用(配图解加讲解)
  5. Android 中单位讲解
  6. 通用高性能 Windows Socket 组件 HP-Socket v2.2.2 更新发布
  7. linux 网络编程:客户端与服务器通过TCP协议相互通信 + UDP
  8. Windows系统架构
  9. angularJS自定义 过滤器基础
  10. Linux centos7环境下安装JDK的步骤详解