Android 7.0:'javax.net.ssl.SSLHandshakeException:连接被对等方关闭
Posted
技术标签:
【中文标题】Android 7.0:\'javax.net.ssl.SSLHandshakeException:连接被对等方关闭【英文标题】:Android 7.0 : 'javax.net.ssl.SSLHandshakeException: Connection closed by peerAndroid 7.0:'javax.net.ssl.SSLHandshakeException:连接被对等方关闭 【发布时间】:2017-09-22 20:26:00 【问题描述】:当我尝试从我的应用程序访问“https”网络服务时,它会给出“javax.net.ssl.SSLHandshakeException: Connection closed by peer”错误。相同的 Web Service 在 Chrome 浏览器中运行良好。
此问题仅在 android 7.0 上发生,它在 Android 6.0 和 5.0 中运行良好。
服务器是 CA 认证的,不是自签名的。
【问题讨论】:
我在下面的帖子***.com/a/54459978/8240915中回答了同样的问题 【参考方案1】:尝试使用此代码,它对我有用:
private static void initializeSSLContext(Context mContext)
try
SSLContext.getInstance("TLSv1.2");
catch (NoSuchAlgorithmException e)
e.printStackTrace();
try
ProviderInstaller.installIfNeeded(mContext.getApplicationContext());
catch (GooglePlayServicesRepairableException e)
e.printStackTrace();
catch (GooglePlayServicesNotAvailableException e)
e.printStackTrace();
别忘了使用 usr google 安全库:
compile 'com.google.android.gms:play-services-safetynet:11.6.2'
【讨论】:
您可以在应用程序类的 onCreate 中添加它,也可以在调用您的服务之前添加它 知道如何将此代码添加到 Cordova/Ionic 应用程序吗? 对不起,我不知道,我之前没有在 Ionic 中编程,但是如果你可以创建一个函数,那么在服务调用之前添加函数的调用(当你调用 api 来连接服务器时) )【参考方案2】:为了解决这个问题,我不得不使用扩展的 SSLSocket 类来包含所有协议和密码套件。解决方案在于 GetProtocolList() & GetCipherList()
private static OkHttpClient.Builder enableAllProtocols(OkHttpClient.Builder client)
try
client.sslSocketFactory(new SSLSocketFactoryExtended(), provideX509TrustManager());
catch (Exception exc)
Log.e("OkHttpTLSCompat", "Error while setting Protocols", exc);
return client;
SSLSocketFactory扩展类文件
public class SSLSocketFactoryExtended extends SSLSocketFactory
private SSLContext mSSLContext;
private String[] mCiphers;
private String[] mProtocols;
public SSLSocketFactoryExtended() throws NoSuchAlgorithmException, KeyManagementException
initSSLSocketFactoryEx(null,null,null);
public String[] getDefaultCipherSuites()
return mCiphers;
public String[] getSupportedCipherSuites()
return mCiphers;
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException
SSLSocketFactory factory = mSSLContext.getSocketFactory();
SSLSocket ss = (SSLSocket)factory.createSocket(s, host, port, autoClose);
ss.setEnabledProtocols(mProtocols);
ss.setEnabledCipherSuites(mCiphers);
return ss;
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException
SSLSocketFactory factory = mSSLContext.getSocketFactory();
SSLSocket ss = (SSLSocket)factory.createSocket(address, port, localAddress, localPort);
ss.setEnabledProtocols(mProtocols);
ss.setEnabledCipherSuites(mCiphers);
return ss;
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException
SSLSocketFactory factory = mSSLContext.getSocketFactory();
SSLSocket ss = (SSLSocket)factory.createSocket(host, port, localHost, localPort);
ss.setEnabledProtocols(mProtocols);
ss.setEnabledCipherSuites(mCiphers);
return ss;
@Override
public Socket createSocket(InetAddress host, int port) throws IOException
SSLSocketFactory factory = mSSLContext.getSocketFactory();
SSLSocket ss = (SSLSocket)factory.createSocket(host, port);
ss.setEnabledProtocols(mProtocols);
ss.setEnabledCipherSuites(mCiphers);
return ss;
@Override
public Socket createSocket(String host, int port) throws IOException
SSLSocketFactory factory = mSSLContext.getSocketFactory();
SSLSocket ss = (SSLSocket)factory.createSocket(host, port);
ss.setEnabledProtocols(mProtocols);
ss.setEnabledCipherSuites(mCiphers);
return ss;
private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException
mSSLContext = SSLContext.getInstance("TLS");
mSSLContext.init(km, tm, random);
mProtocols = GetProtocolList();
mCiphers = GetCipherList();
protected String[] GetProtocolList()
String[] protocols = "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3";
String[] availableProtocols = null;
SSLSocket socket = null;
try
SSLSocketFactory factory = mSSLContext.getSocketFactory();
socket = (SSLSocket)factory.createSocket();
availableProtocols = socket.getSupportedProtocols();
catch(Exception e)
return new String[] "TLSv1" ;
finally
if(socket != null)
try
socket.close();
catch (IOException e)
List<String> resultList = new ArrayList<String>();
for(int i = 0; i < protocols.length; i++)
int idx = Arrays.binarySearch(availableProtocols, protocols[i]);
if(idx >= 0)
resultList.add(protocols[i]);
return resultList.toArray(new String[0]);
protected String[] GetCipherList()
List<String> resultList = new ArrayList<String>();
SSLSocketFactory factory = mSSLContext.getSocketFactory();
for(String s : factory.getSupportedCipherSuites())
resultList.add(s);
return resultList.toArray(new String[resultList.size()]);
【讨论】:
这段代码效果很好。该服务器是旧的 WIndows 2003 服务器。不支持 TLS 1.2 对了,这个怎么用?以上是关于Android 7.0:'javax.net.ssl.SSLHandshakeException:连接被对等方关闭的主要内容,如果未能解决你的问题,请参考以下文章
Android 7.0下仿7.0之前的时间框及去掉日选择框方法
关于 Android 7.0 适配中 FileProvider 部分的总结