如何在android中为HttpsUrlConnection禁用SSLv3?

如何在android中为HttpsUrlConnection禁用SSLv3?,第1张

如何在android中为HttpsUrlConnection禁用SSLv3?

通过使用wireshark分析数据包,我找到了解决方案。我发现,在建立安全连接的同时,android从TLSv1退回到SSLv3。这是Android版本<4.4中的错误,可以通过从“启用的协议”列表中删除SSLv3协议来解决。我制作了一个名为NoSSLv3SocketFactory.java的自定义socketFactory类。使用它来创建一个套接字工厂。

import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;import java.net.SocketAddress;import java.net.SocketException;import java.nio.channels.SocketChannel;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import javax.net.ssl.HandshakeCompletedListener;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLSession;import javax.net.ssl.SSLSocket;import javax.net.ssl.SSLSocketFactory;public class NoSSLv3SocketFactory extends SSLSocketFactory{    private final SSLSocketFactory delegate;public NoSSLv3SocketFactory() {    this.delegate = HttpsURLConnection.getDefaultSSLSocketFactory();}public NoSSLv3SocketFactory(SSLSocketFactory delegate) {    this.delegate = delegate;}@Overridepublic String[] getDefaultCipherSuites() {    return delegate.getDefaultCipherSuites();}@Overridepublic String[] getSupportedCipherSuites() {    return delegate.getSupportedCipherSuites();}private Socket makeSocketSafe(Socket socket) {    if (socket instanceof SSLSocket) {        socket = new NoSSLv3SSLSocket((SSLSocket) socket);    }    return socket;}@Overridepublic Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {    return makeSocketSafe(delegate.createSocket(s, host, port, autoClose));}@Overridepublic Socket createSocket(String host, int port) throws IOException {    return makeSocketSafe(delegate.createSocket(host, port));}@Overridepublic Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {    return makeSocketSafe(delegate.createSocket(host, port, localHost, localPort));}@Overridepublic Socket createSocket(InetAddress host, int port) throws IOException {    return makeSocketSafe(delegate.createSocket(host, port));}@Overridepublic Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {    return makeSocketSafe(delegate.createSocket(address, port, localAddress, localPort));}private class NoSSLv3SSLSocket extends DelegateSSLSocket {    private NoSSLv3SSLSocket(SSLSocket delegate) {        super(delegate);    }    @Override    public void setEnabledProtocols(String[] protocols) {        if (protocols != null && protocols.length == 1 && "SSLv3".equals(protocols[0])) { List<String> enabledProtocols = new ArrayList<String>(Arrays.asList(delegate.getEnabledProtocols())); if (enabledProtocols.size() > 1) {     enabledProtocols.remove("SSLv3");     System.out.println("Removed SSLv3 from enabled protocols"); } else {     System.out.println("SSL stuck with protocol available for " + String.valueOf(enabledProtocols)); } protocols = enabledProtocols.toArray(new String[enabledProtocols.size()]);        }        super.setEnabledProtocols(protocols);    }}public class DelegateSSLSocket extends SSLSocket {    protected final SSLSocket delegate;    DelegateSSLSocket(SSLSocket delegate) {        this.delegate = delegate;    }    @Override    public String[] getSupportedCipherSuites() {        return delegate.getSupportedCipherSuites();    }    @Override    public String[] getEnabledCipherSuites() {        return delegate.getEnabledCipherSuites();    }    @Override    public void setEnabledCipherSuites(String[] suites) {        delegate.setEnabledCipherSuites(suites);    }    @Override    public String[] getSupportedProtocols() {        return delegate.getSupportedProtocols();    }    @Override    public String[] getEnabledProtocols() {        return delegate.getEnabledProtocols();    }    @Override    public void setEnabledProtocols(String[] protocols) {        delegate.setEnabledProtocols(protocols);    }    @Override    public SSLSession getSession() {        return delegate.getSession();    }    @Override    public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {        delegate.addHandshakeCompletedListener(listener);    }    @Override    public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {        delegate.removeHandshakeCompletedListener(listener);    }    @Override    public void startHandshake() throws IOException {        delegate.startHandshake();    }    @Override    public void setUseClientMode(boolean mode) {        delegate.setUseClientMode(mode);    }    @Override    public boolean getUseClientMode() {        return delegate.getUseClientMode();    }    @Override    public void setNeedClientAuth(boolean need) {        delegate.setNeedClientAuth(need);    }    @Override    public void setWantClientAuth(boolean want) {        delegate.setWantClientAuth(want);    }    @Override    public boolean getNeedClientAuth() {        return delegate.getNeedClientAuth();    }    @Override    public boolean getWantClientAuth() {        return delegate.getWantClientAuth();    }    @Override    public void setEnableSessionCreation(boolean flag) {        delegate.setEnableSessionCreation(flag);    }    @Override    public boolean getEnableSessionCreation() {        return delegate.getEnableSessionCreation();    }    @Override    public void bind(SocketAddress localAddr) throws IOException {        delegate.bind(localAddr);    }    @Override    public synchronized void close() throws IOException {        delegate.close();    }    @Override    public void connect(SocketAddress remoteAddr) throws IOException {        delegate.connect(remoteAddr);    }    @Override    public void connect(SocketAddress remoteAddr, int timeout) throws IOException {        delegate.connect(remoteAddr, timeout);    }    @Override    public SocketChannel getChannel() {        return delegate.getChannel();    }    @Override    public InetAddress getInetAddress() {        return delegate.getInetAddress();    }    @Override    public InputStream getInputStream() throws IOException {        return delegate.getInputStream();    }    @Override    public boolean getKeepAlive() throws SocketException {        return delegate.getKeepAlive();    }    @Override    public InetAddress getLocalAddress() {        return delegate.getLocalAddress();    }    @Override    public int getLocalPort() {        return delegate.getLocalPort();    }    @Override    public SocketAddress getLocalSocketAddress() {        return delegate.getLocalSocketAddress();    }    @Override    public boolean getOOBInline() throws SocketException {        return delegate.getOOBInline();    }    @Override    public OutputStream getOutputStream() throws IOException {        return delegate.getOutputStream();    }    @Override    public int getPort() {        return delegate.getPort();    }    @Override    public synchronized int getReceiveBufferSize() throws SocketException {        return delegate.getReceiveBufferSize();    }    @Override    public SocketAddress getRemoteSocketAddress() {        return delegate.getRemoteSocketAddress();    }    @Override    public boolean getReuseAddress() throws SocketException {        return delegate.getReuseAddress();    }    @Override    public synchronized int getSendBufferSize() throws SocketException {        return delegate.getSendBufferSize();    }    @Override    public int getSoLinger() throws SocketException {        return delegate.getSoLinger();    }    @Override    public synchronized int getSoTimeout() throws SocketException {        return delegate.getSoTimeout();    }    @Override    public boolean getTcpNoDelay() throws SocketException {        return delegate.getTcpNoDelay();    }    @Override    public int getTrafficClass() throws SocketException {        return delegate.getTrafficClass();    }    @Override    public boolean isBound() {        return delegate.isBound();    }    @Override    public boolean isClosed() {        return delegate.isClosed();    }    @Override    public boolean isConnected() {        return delegate.isConnected();    }    @Override    public boolean isInputShutdown() {        return delegate.isInputShutdown();    }    @Override    public boolean isOutputShutdown() {        return delegate.isOutputShutdown();    }    @Override    public void sendUrgentData(int value) throws IOException {        delegate.sendUrgentData(value);    }    @Override    public void setKeepAlive(boolean keepAlive) throws SocketException {        delegate.setKeepAlive(keepAlive);    }    @Override    public void setOOBInline(boolean oobinline) throws SocketException {        delegate.setOOBInline(oobinline);    }    @Override    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {        delegate.setPerformancePreferences(connectionTime, latency, bandwidth);    }    @Override    public synchronized void setReceiveBufferSize(int size) throws SocketException {        delegate.setReceiveBufferSize(size);    }    @Override    public void setReuseAddress(boolean reuse) throws SocketException {        delegate.setReuseAddress(reuse);    }    @Override    public synchronized void setSendBufferSize(int size) throws SocketException {        delegate.setSendBufferSize(size);    }    @Override    public void setSoLinger(boolean on, int timeout) throws SocketException {        delegate.setSoLinger(on, timeout);    }    @Override    public synchronized void setSoTimeout(int timeout) throws SocketException {        delegate.setSoTimeout(timeout);    }    @Override    public void setTcpNoDelay(boolean on) throws SocketException {        delegate.setTcpNoDelay(on);    }    @Override    public void setTrafficClass(int value) throws SocketException {        delegate.setTrafficClass(value);    }    @Override    public void shutdownInput() throws IOException {        delegate.shutdownInput();    }    @Override    public void shutdownOutput() throws IOException {        delegate.shutdownOutput();    }    @Override    public String toString() {        return delegate.toString();    }    @Override    public boolean equals(Object o) {        return delegate.equals(o);    }}}

在连接时像这样使用此类:

SSLContext sslcontext = SSLContext.getInstance("TLSv1"); sslcontext.init(null,         null,         null); SSLSocketFactory NoSSLv3Factory = new NoSSLv3SocketFactory(sslcontext.getSocketFactory()); HttpsURLConnection.setDefaultSSLSocketFactory(NoSSLv3Factory); l_connection = (HttpsURLConnection) l_url.openConnection(); l_connection.connect();

更新:

现在,正确的解决方案是使用Google Play服务安装更新的安全提供程序

    ProviderInstaller.installIfNeeded(getApplicationContext());

这有效地使您的应用程序可以访问较新版本的OpenSSL和Java安全提供程序,其中包括对SSLEngine中的TLSv1.2的支持。一旦安装了新的提供程序,就可以创建SSLEngine,以通常的方式支持SSLv3,TLSv1,TLSv1.1和TLSv1.2:

    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");    sslContext.init(null, null, null);    SSLEngine engine = sslContext.createSSLEngine();

或者,您可以使用来限制已启用的协议engine.setEnabledProtocols。

不要忘记添加以下依赖项(在此处找到最新版本):

compile 'com.google.android.gms:play-services-auth:11.8.0'


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5561845.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-14
下一篇2022-12-14

发表评论

登录后才能评论

评论列表(0条)

    保存