How to override the cipherlist sent to the server by Android when using HttpsURLConnection?

后端 未结 3 933
既然无缘
既然无缘 2020-11-30 06:19

During TLS negotiation, clients send a list of supported ciphers to the server, the server picks one, and encryption starts. I want to change this cipherlist sent to the ser

3条回答
  •  醉梦人生
    2020-11-30 06:52

    This piece of code is a bit raw. please use with care.

    public class PreferredCipherSuiteSSLSocketFactory extends SSLSocketFactory {
    
    
    private static final String PREFERRED_CIPHER_SUITE = "TLS_RSA_WITH_AES_128_CBC_SHA";
    
    private final SSLSocketFactory delegate;
    
    public PreferredCipherSuiteSSLSocketFactory(SSLSocketFactory delegate) {
    
        this.delegate = delegate;
    }
    
    @Override
    public String[] getDefaultCipherSuites() {
    
        return setupPreferredDefaultCipherSuites(this.delegate);
    }
    
    @Override
    public String[] getSupportedCipherSuites() {
    
        return setupPreferredSupportedCipherSuites(this.delegate);
    }
    
    @Override
    public Socket createSocket(String arg0, int arg1) throws IOException,
            UnknownHostException {
    
        Socket socket = this.delegate.createSocket(arg0, arg1);
        String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
        ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);
    
        return socket;
    }
    
    @Override
    public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
    
        Socket socket = this.delegate.createSocket(arg0, arg1);
        String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
        ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);
    
        return socket;
    }
    
    @Override
    public Socket createSocket(Socket arg0, String arg1, int arg2, boolean arg3)
            throws IOException {
    
        Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3);
        String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
        ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);
    
        return socket;
    }
    
    @Override
    public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
            throws IOException, UnknownHostException {
    
        Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3);
        String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
        ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);
    
        return socket;
    }
    
    @Override
    public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2,
            int arg3) throws IOException {
    
        Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3);
        String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
        ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);
    
        return socket;
    }
    
    private static String[] setupPreferredDefaultCipherSuites(SSLSocketFactory sslSocketFactory) {
    
        String[] defaultCipherSuites = sslSocketFactory.getDefaultCipherSuites();
    
        ArrayList suitesList = new ArrayList(Arrays.asList(defaultCipherSuites));
        suitesList.remove(PREFERRED_CIPHER_SUITE);
        suitesList.add(0, PREFERRED_CIPHER_SUITE);
    
        return suitesList.toArray(new String[suitesList.size()]);
    }
    
    private static String[] setupPreferredSupportedCipherSuites(SSLSocketFactory sslSocketFactory) {
    
        String[] supportedCipherSuites = sslSocketFactory.getSupportedCipherSuites();
    
        ArrayList suitesList = new ArrayList(Arrays.asList(supportedCipherSuites));
        suitesList.remove(PREFERRED_CIPHER_SUITE);
        suitesList.add(0, PREFERRED_CIPHER_SUITE);
    
        return suitesList.toArray(new String[suitesList.size()]);
    }
    }
    

    When you want to use it.

                HttpsURLConnection connection = (HttpsURLConnection) (new URL(url))
                    .openConnection();
            SSLContext context = SSLContext.getInstance("TLS");
            TrustManager tm[] = {new SSLPinningTrustManager()};
            context.init(null, tm, null);
            SSLSocketFactory preferredCipherSuiteSSLSocketFactory = new PreferredCipherSuiteSSLSocketFactory(context.getSocketFactory());
            connection.setSSLSocketFactory(preferredCipherSuiteSSLSocketFactory);
                        connection.connect();
    

    Thanks you.

提交回复
热议问题