亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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

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

人到中年有點甜 2019-12-21 11:11:21
我正在開發一個應用程序,(高級)用戶必須為此設置他們自己的服務器(即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警報握手失?。y試ECDHE-ECDSA-AES256-SHA384 ... NO(sslv3警報握手失敗)測試ECDHE-RSA-AES256-SHA ... NO(sslv3警報握手失?。y試ECDHE-ECDSA-AES256-SHA ... NO(sslv3警報握手失敗)測試SRP-DSS-AES-256-CBC-SHA ...否(sslv3警報握手失?。y試SRP-RSA-AES-256-CBC-SHA ... NO(sslv3警報握手失?。y試DHE-DSS-AES256-GCM-SHA384 ...否(sslv3警報握手失敗)測試DHE-RSA-AES256-GCM-SHA384 ...否(sslv3警報握手失?。y試DHE-RSA-AES256-SHA256 ... NO(sslv3警報握手失?。y試DHE-DSS-AES256-SHA256 ... NO(sslv3警報握手失敗)測試DHE-RSA-AES256-SHA ... NO(sslv3警報握手失?。y試DHE-DSS-AES256-SHA ...否(sslv3警報握手失敗)測試DHE-RSA-CAMELLIA256-SHA ... NO(sslv3警報握手失?。┪铱梢栽诜抡嫫鞯臑g覽器中打開服務器URL,并獲得完美的json響應,因此我知道系統本身具有功能。所以問題是,為什么我不能在Android 7上連接?
查看完整描述

3 回答

?
波斯汪

TA貢獻1811條經驗 獲得超4個贊

在這里,您是Volley的工作解決方案:


在以單例代碼創建隊列之前:


public class VolleyServiceSingleton {


    private RequestQueue mRequestQueue;

    private HurlStack mStack;


    private VolleyServiceSingleton(){


        SSLSocketFactoryExtended factory = null;


        try {

            factory = new SSLSocketFactoryExtended();

        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();

        } catch (KeyManagementException e) {

            e.printStackTrace();

        }



        final SSLSocketFactoryExtended finalFactory = factory;

        mStack = new HurlStack() {

            @Override

            protected HttpURLConnection createConnection(URL url) throws IOException {

                HttpsURLConnection httpsURLConnection = (HttpsURLConnection) super.createConnection(url);

                try {

                    httpsURLConnection.setSSLSocketFactory(finalFactory);

                    httpsURLConnection.setRequestProperty("charset", "utf-8");


                } catch (Exception e) {

                    e.printStackTrace();

                }

                return httpsURLConnection;

            }


        };




        mRequestQueue = Volley.newRequestQueue(YourApplication.getContext(), mStack, -1);    


    }



}

這是SSLSocketFactoryExtended:


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;

    }


    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;

    }


    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;

    }


    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()){

            Log.e("CipherSuite type = ",s);

            resultList.add(s);

        }

        return resultList.toArray(new String[resultList.size()]);

    }


}

在此代碼中,我簡單地添加設備支持的所有密碼,對我來說這是可行的),可能會幫助某人)(干杯)


ps無需在清單中添加安全網絡配置參數。


查看完整回答
反對 回復 2019-12-21
  • 3 回答
  • 0 關注
  • 1018 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號