SSLHandshakeException:在Android N / 7.0上握手失败

我正在开发一个应用程序,(高级)用户必须为此设置他们自己的服务器(即nginx)来运行后端应用程序。需要在应用程序中配置相应的域,以便它可以连接。我主要在自己的手机(sony z3c)上进行测试,并开始为5.1开发。后来我收到了6.0的更新,但在仿真器中仍保持有效的5.1。不久之前,我开始使用具有7.0映像的AVD进行工作,但我惊讶地发现它无法连接到服务器,并告诉我SSL握手失败。我的nginx配置非常严格,但它同时适用于5.1和6.0,所以....?!

这是我所知道的:

  • 我使用v24作为支持库,即我的compileSdkVersion为24。

  • 我使用Volley v1.0.0。

  • 我已经尝试了TLSSocketFactory,但是它没有任何改变。无论如何,似乎大多数时候都使用此方法来防止将SSL3用于较早的SDK版本。

  • 我尝试增加超时时间,但是它没有任何改变。

  • 我已经尝试过直接使用HttpURLConnection,但是除了堆栈跟踪,它没有任何改变(它没有凌空引用,但是完全相同)。

如果没有TLSSocketFactory,则请求是通过裸请求队列发出的,使用实例化Volley.newRequestQueue(context)

因为它说SSLV3_ALERT_HANDSHAKE_FAILURE我只能假设由于某种原因尝试使用SSLv3进行连接而失败,但这对我来说毫无意义。它可能是一个密码问题,但是我怎么知道它试图使用什么呢?我宁愿不启用服务器上的密码,进行连接尝试并重复。


我的nginx站点使用一个“让我们加密”证书,并具有以下配置:


ssl_stapling on;

ssl_stapling_verify on;

ssl_trusted_certificate /etc/ssl/certs/lets-encrypt-x1-cross-signed.pem;

ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:!aNULL;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

ssl_ecdh_curve secp384r1;

ssl_prefer_server_ciphers on;

ssl_protocols TLSv1.2;

为了测试这些密码,我有一个脚本,它可以确认这些密码(在服务器网络外部的微调vps上运行):


测试ECDHE-RSA-AES256-GCM-SHA384 ...是

测试ECDHE-ECDSA-AES256-GCM-SHA384 ...否(sslv3警报握手失败)

测试ECDHE-RSA-AES256-SHA384 ... NO(sslv3警报握手失败)

测试ECDHE-ECDSA-AES256-SHA384 ... NO(sslv3警报握手失败)

测试ECDHE-RSA-AES256-SHA ... NO(sslv3警报握手失败)

测试ECDHE-ECDSA-AES256-SHA ... NO(sslv3警报握手失败)

测试SRP-DSS-AES-256-CBC-SHA ...否(sslv3警报握手失败)

测试SRP-RSA-AES-256-CBC-SHA ... NO(sslv3警报握手失败)

测试DHE-DSS-AES256-GCM-SHA384 ...否(sslv3警报握手失败)

测试DHE-RSA-AES256-GCM-SHA384 ...否(sslv3警报握手失败)

测试DHE-RSA-AES256-SHA256 ... NO(sslv3警报握手失败)

测试DHE-DSS-AES256-SHA256 ... NO(sslv3警报握手失败)

测试DHE-RSA-AES256-SHA ... NO(sslv3警报握手失败)

测试DHE-DSS-AES256-SHA ...否(sslv3警报握手失败)

测试DHE-RSA-CAMELLIA256-SHA ... NO(sslv3警报握手失败)

我可以在仿真器的浏览器中打开服务器URL,并获得完美的json响应,因此我知道系统本身具有功能。


所以问题是,为什么我不能在Android 7上连接?


人到中年有点甜
浏览 877回答 3
3回答

波斯汪

在这里,您是Volley的工作解决方案:在以单例代码创建队列之前:public class VolleyServiceSingleton {&nbsp; &nbsp; private RequestQueue mRequestQueue;&nbsp; &nbsp; private HurlStack mStack;&nbsp; &nbsp; private VolleyServiceSingleton(){&nbsp; &nbsp; &nbsp; &nbsp; SSLSocketFactoryExtended factory = null;&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; factory = new SSLSocketFactoryExtended();&nbsp; &nbsp; &nbsp; &nbsp; } catch (NoSuchAlgorithmException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; } catch (KeyManagementException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; final SSLSocketFactoryExtended finalFactory = factory;&nbsp; &nbsp; &nbsp; &nbsp; mStack = new HurlStack() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; protected HttpURLConnection createConnection(URL url) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HttpsURLConnection httpsURLConnection = (HttpsURLConnection) super.createConnection(url);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; httpsURLConnection.setSSLSocketFactory(finalFactory);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; httpsURLConnection.setRequestProperty("charset", "utf-8");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (Exception e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return httpsURLConnection;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; mRequestQueue = Volley.newRequestQueue(YourApplication.getContext(), mStack, -1);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }}这是SSLSocketFactoryExtended:public class SSLSocketFactoryExtended extends SSLSocketFactory{&nbsp; &nbsp; private SSLContext mSSLContext;&nbsp; &nbsp; private String[] mCiphers;&nbsp; &nbsp; private String[] mProtocols;&nbsp; &nbsp; public SSLSocketFactoryExtended() throws NoSuchAlgorithmException, KeyManagementException&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; initSSLSocketFactoryEx(null,null,null);&nbsp; &nbsp; }&nbsp; &nbsp; public String[] getDefaultCipherSuites()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return mCiphers;&nbsp; &nbsp; }&nbsp; &nbsp; public String[] getSupportedCipherSuites()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return mCiphers;&nbsp; &nbsp; }&nbsp; &nbsp; public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; SSLSocketFactory factory = mSSLContext.getSocketFactory();&nbsp; &nbsp; &nbsp; &nbsp; SSLSocket ss = (SSLSocket)factory.createSocket(s, host, port, autoClose);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledProtocols(mProtocols);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledCipherSuites(mCiphers);&nbsp; &nbsp; &nbsp; &nbsp; return ss;&nbsp; &nbsp; }&nbsp; &nbsp; public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; SSLSocketFactory factory = mSSLContext.getSocketFactory();&nbsp; &nbsp; &nbsp; &nbsp; SSLSocket ss = (SSLSocket)factory.createSocket(address, port, localAddress, localPort);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledProtocols(mProtocols);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledCipherSuites(mCiphers);&nbsp; &nbsp; &nbsp; &nbsp; return ss;&nbsp; &nbsp; }&nbsp; &nbsp; public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; SSLSocketFactory factory = mSSLContext.getSocketFactory();&nbsp; &nbsp; &nbsp; &nbsp; SSLSocket ss = (SSLSocket)factory.createSocket(host, port, localHost, localPort);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledProtocols(mProtocols);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledCipherSuites(mCiphers);&nbsp; &nbsp; &nbsp; &nbsp; return ss;&nbsp; &nbsp; }&nbsp; &nbsp; public Socket createSocket(InetAddress host, int port) throws IOException&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; SSLSocketFactory factory = mSSLContext.getSocketFactory();&nbsp; &nbsp; &nbsp; &nbsp; SSLSocket ss = (SSLSocket)factory.createSocket(host, port);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledProtocols(mProtocols);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledCipherSuites(mCiphers);&nbsp; &nbsp; &nbsp; &nbsp; return ss;&nbsp; &nbsp; }&nbsp; &nbsp; public Socket createSocket(String host, int port) throws IOException&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; SSLSocketFactory factory = mSSLContext.getSocketFactory();&nbsp; &nbsp; &nbsp; &nbsp; SSLSocket ss = (SSLSocket)factory.createSocket(host, port);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledProtocols(mProtocols);&nbsp; &nbsp; &nbsp; &nbsp; ss.setEnabledCipherSuites(mCiphers);&nbsp; &nbsp; &nbsp; &nbsp; return ss;&nbsp; &nbsp; }&nbsp; &nbsp; private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws NoSuchAlgorithmException, KeyManagementException&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; mSSLContext = SSLContext.getInstance("TLS");&nbsp; &nbsp; &nbsp; &nbsp; mSSLContext.init(km, tm, random);&nbsp; &nbsp; &nbsp; &nbsp; mProtocols = GetProtocolList();&nbsp; &nbsp; &nbsp; &nbsp; mCiphers = GetCipherList();&nbsp; &nbsp; }&nbsp; &nbsp; protected String[] GetProtocolList()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; String[] protocols = { "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"};&nbsp; &nbsp; &nbsp; &nbsp; String[] availableProtocols = null;&nbsp; &nbsp; &nbsp; &nbsp; SSLSocket socket = null;&nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SSLSocketFactory factory = mSSLContext.getSocketFactory();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; socket = (SSLSocket)factory.createSocket();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; availableProtocols = socket.getSupportedProtocols();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch(Exception e)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new String[]{ "TLSv1" };&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; finally&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(socket != null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; socket.close();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; List<String> resultList = new ArrayList<String>();&nbsp; &nbsp; &nbsp; &nbsp; for(int i = 0; i < protocols.length; i++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int idx = Arrays.binarySearch(availableProtocols, protocols[i]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(idx >= 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resultList.add(protocols[i]);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return resultList.toArray(new String[0]);&nbsp; &nbsp; }&nbsp; &nbsp; protected String[] GetCipherList()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; List<String> resultList = new ArrayList<String>();&nbsp; &nbsp; &nbsp; &nbsp; SSLSocketFactory factory = mSSLContext.getSocketFactory();&nbsp; &nbsp; &nbsp; &nbsp; for(String s : factory.getSupportedCipherSuites()){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Log.e("CipherSuite type = ",s);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resultList.add(s);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return resultList.toArray(new String[resultList.size()]);&nbsp; &nbsp; }}在此代码中,我简单地添加设备支持的所有密码,对我来说这是可行的),可能会帮助某人)(干杯)ps无需在清单中添加安全网络配置参数。
打开App,查看更多内容
随时随地看视频慕课网APP