peer not authenticated的终极解决方案
一、前述
使用httpclient发起https请求时,可能会遇到如下异常:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:399)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143)
网上搜索也能找到一大堆的解决方案,但大部分都类似,就是跳过证书的验证,于是跟着稀里糊涂的将代码拷贝下来使用,结果呢?有的能解决,有的依旧报这个错误。到底咋回事呢,接下来就说说这个问题的解决方案。
二、缘由
首先,要知道导致报这个异常的原因不仅仅是因为证书校验不通过。
都知道,在我们通过https链接服务器时,服务器会给我们返回一个证书,这个证书可能经过CA认证,也可能是未认证的自制证书,客户端拿到这个证书后会对这个证书进行验证,如果是经过CA验证的证书,自然证书校验就能通过,自制证书自然就校验不同过,从而导致上边的异常。
证书校验通过后,还需要校验访问的域名是否和证书指定的域名是否匹配。未匹配也会导致如上异常。
上边两步都校验通过了才开始进行握手,但握手也有可能失败,从而导致上边的异常。
以上三个步骤中任何一个出了问题,都会连接失败。
三、解决方法
通过网上搜索我们大部分都会找到类似如下的解决方案:
SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("SSL");
// set up a TrustManager that trusts everything
try {
sslContext.init(null,
new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
} public void checkClientTrusted(
X509Certificate[] certs, String authType) {
} public void checkServerTrusted(
X509Certificate[] certs, String authType) {
}
} }, new SecureRandom());
} catch (KeyManagementException e) {
}
SSLSocketFactory ssf = new SSLSocketFactory(sslContext,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
这个解决方案针对以上的三个步骤中的第一步,就是放弃对证书的校验,但是第二部还可能有问题,要想彻底解决还需要跳过对域名的校验。这里给出最终的解决方案:
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null,new TrustManager[]{tm},null);
sslSocketFactory = new SSLSocketFactory(sslContext,new X509HostnameVerifier(){
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
}
});
} catch (GeneralSecurityException e) {
log.error("create SSLSocketFactory error:{}",e);
}
return sslSocketFactory;
这里不仅放弃对证书的校验,也放弃对hostname的校验,通过空实现X509HostnameVerifier类。
以上这个解决方案就会彻底解决问题吗?不一定,还有一个步骤就是握手的步骤也可能出问题,怎么判断是不是握手步骤出了问题呢?可以在代码里做如下设置:
System.setProperty("javax.net.debug","ssl");
做了以上设置后,就可以打印https建立连接的日志了,如下:
true
addingastrustedcert:
证书内容略去
triggerseedingofSecureRandom
doneseedingSecureRandom
executingrequestGETHTTP/1.1
Ignoringunavailableciphersuite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoringunavailableciphersuite:TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoringunavailableciphersuite:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoringunsupportedciphersuite:TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoringunsupportedciphersuite:TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoringunsupportedciphersuite:TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoringunsupportedciphersuite:TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoringunsupportedciphersuite:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoringunsupportedciphersuite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoringunsupportedciphersuite:TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoringunsupportedciphersuite:TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoringunavailableciphersuite:TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoringunsupportedciphersuite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoringunsupportedciphersuite:TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoringunavailableciphersuite:TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoringunsupportedciphersuite:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoringunsupportedciphersuite:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoringunsupportedciphersuite:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoringunavailableciphersuite:TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoringunavailableciphersuite:TLS_RSA_WITH_AES_256_CBC_SHA
Ignoringunsupportedciphersuite:TLS_RSA_WITH_AES_128_CBC_SHA256
Allowunsaferenegotiation:false
Allowlegacyhellomessages:true
Isinitialhandshake:true
Issecurerenegotiation:false
%%Nocachedclientsession
***ClientHello,TLSv1
……
main,WRITE:TLSv1Handshake,length=181
main,READ:TLSv1Alert,length=2
main,RECVTLSv1ALERT:fatal,handshake_failure
main,calledcloseSocket()
main,handlingexception:javax.net.ssl.SSLHandshakeException:Receivedfatalalert:handshake_failure
通过最后一个词组“handshake_failure”,你一定可以确定是握手失败了。这一般是因为客户端的加密机制太简单,服务器认为不安全,握手失败。
握手失败解决方案就比较简单,下载一个UnlimitedJCEPolicyJDK7.zip 。在http://www.oracle.com/technetwork/java/javase/downloads/index.html下载就好了。里面包含了两个jar。在你的/lib/security,替换后,重新运行看看。
如果以上这些还没能解决,那我也是不知道了,可以留言,我跟你一块找答案^_^。
peer not authenticated的终极解决方案的更多相关文章
- peer not authenticated error
问题背景 系统:OS X El Capitan,10.11.2 IDE:Android Studio 2.0 Preview Java:1.8.0_65 Gradle:2.3 clone了代码后,在i ...
- 导入安卓项目的时候,发生错误:Cause: peer not authenticated
导入安卓项目时出现Cause: peer not authenticated. 在网上搜了解决方案,都没有凑效.后来干脆插上手机直接debug安装,竟然成功了,成功了,成功了!!!! 然后再次buil ...
- Eclipse不自动编译java文件的终极解决方案
最近我的eclipse经常犯傻,项目中总是有很多,启动项目也是没有启动类.查了下项目中生成的class文件,我靠竟然没有,或者还是以前的.原来是eclipse犯傻了,它没帮我自动编译java文件.一般 ...
- 【转】JSP中文乱码问题终极解决方案
原文地址:http://blog.csdn.net/beijiguangyong/article/details/7414247 在介绍方法之前我们首先应该清楚具体的问题有哪些,笔者在本博客当中论述的 ...
- Xcode-调试断点不能停在代码区终极解决方案
转发 调试断点不能停在代码区终极解决方案: http://mobile.51cto.com/iphone-390082.htm
- VIM、GVIM在WINDOWS下中文乱码的终极解决方案
文章转自:http://www.liuhuadong.com/archives/68 vim.gvim在windows下中文乱码的终极解决方案在windows下vim的中文字体显示并不好,所以我们需要 ...
- Android大图片裁剪终极解决方案(上:原理分析)
转载声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-) http://my.oschina.net/ryanhoo/blog/86842 约几个月前,我正 ...
- 【原创】CHROME 最小字体限制为12PX的终极解决方案
CHROME 最小字体限制为12PX的终极解决方案 本文由五月雨恋提供,转载请注明出处. 相信不少做网站的用户会有这样一个问题,Chrome 默认最小字体是12px(最新版英文也有此问题),这个是 C ...
- 绝对好文C#调用C++DLL传递结构体数组的终极解决方案
C#调用C++DLL传递结构体数组的终极解决方案 时间 2013-09-17 18:40:56 CSDN博客相似文章 (0) 原文 http://blog.csdn.net/xxdddail/art ...
随机推荐
- 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇
什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ...
- CYQ.Data、ASP.NET Aries 百家企业使用名单
如果您或您所在的公司正在使用此框架,请联系左侧的扣扣,告知我信息,我将为您添加链接: 以下内容为已反馈的用户,(收集始于:2016-08-08),仅展示99家: 序号 企业名称 企业网址 备注 1 山 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(65)-MVC WebApi 用户验证 (1)
系列目录 前言: WebAPI主要开放数据给手机APP,其他需要得知数据的系统,或者软件应用,所以移动端与系统的数据源往往是相通的. Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能, ...
- 编写自己的PHP MVC框架笔记
1.MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller). ...
- JAVA面试题
在这里我将收录我面试过程中遇到的一些好玩的面试题目 第一个面试题:ABC问题,有三个线程,工作的内容分别是打印出"A""B""C",需要做的 ...
- 烂泥:数据库管理之phpmyadmin免密码配置
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 其实这篇文章很早就想写了,但是一直没有时间.刚好今天下午稍微空了点,就把这篇文章整理出来 ...
- Visual Studio 2015正式发布
Windows 10 RTM正式版要7月29日发布,微软的另一个重磅软件Visual Studio 2015已经率先发布,今天如期放出了正式版本.Visual Studio 2015包括许多新功能和更 ...
- C#开源实现MJPEG流传输
本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 许久以前写了篇文章<基于.NET打造IP智能网络视频监控系统>,记录和介绍了自己几年来积 ...
- Sublime Text 全程指引 by Lucida
作者:Lucida 微博:@peng_gong 豆瓣:@figure9 博客园:@figure9 原文链接:http://zh.lucida.me/blog/sublime-text-complete ...
- CSharpGL(9)解析OBJ文件并用CSharpGL渲染
CSharpGL(9)解析OBJ文件并用CSharpGL渲染 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo ...