gpt4 book ai didi

Android 4.2.2,如何为 HttpsURLConnection 启用 TLS 1.2?

转载 作者:搜寻专家 更新时间:2023-11-01 08:35:05 24 4
gpt4 key购买 nike

我正在为 API 级别 16+ 开发一个 Android 应用程序,据我所知,默认情况下支持 TLS v1.1 和 TLS v1.2,但在 Android 4.1+ 上未启用

我从这里使用了 SSLSocketFacory:

http://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/

我已经设法使用以下示例:

public class TLSSocketFactory extends SSLSocketFactory {

private SSLSocketFactory internalSSLSocketFactory;

public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.getSocketFactory();

}

@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}

@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}

public Socket createSocket() throws IOException{
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}

@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}

@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}

@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}

@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}

@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}

private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}

我用下面的方式来调用它:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

try{

SSLContext context = SSLContext.getDefault();
TLSSocketFactory factory = new TLSSocketFactory();
SSLSocket socket = (SSLSocket)factory.createSocket();
String[] protocols = socket.getSupportedProtocols();

// this now has the correct protocols enabled for sockets
String[] enabled = socket.getEnabledProtocols();



HttpsURLConnection.setDefaultSSLSocketFactory(new TLSSocketFactory());
URL url = new URL("https://mysslsite/");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(new TLSSocketFactory());

Log.i("", "");
}catch(Exception ex){
ex.printStackTrace();
}
}
}

我可以看到对于套接字连接,我现在有正确启用的协议(protocol),但是如何为 url 连接启用这些协议(protocol)?我还如何验证是否已为 HttpsURLConnection 启用这些协议(protocol)?

我已尝试为连接设置 ssl 套接字工厂,但我不确定如何验证协议(protocol)是否已启用?

更新:我修改了我的代码如下:

                    String myURL = "https://mysslservice";
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, null, null);
SSLSocketFactory noSSLv3Factory = new NoSSLv3SocketFactory(sslcontext.getSocketFactory());
HttpsURLConnection.setDefaultSSLSocketFactory(noSSLv3Factory);

URL url = new URL(myURL);

HttpsURLConnection l_connection = (HttpsURLConnection) url.openConnection();
l_connection.connect();

我使用了 SSL 工厂的以下实现

公共(public)类 NoSSLv3SocketFactory 扩展了 SSLSocketFactory{ 私有(private)最终 SSLSocketFactory 委托(delegate);

public NoSSLv3SocketFactory() {
this.delegate = HttpsURLConnection.getDefaultSSLSocketFactory();
}

public NoSSLv3SocketFactory(SSLSocketFactory delegate) {
this.delegate = delegate;
}

@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}

@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}

private Socket makeSocketSafe(Socket socket) {
if (socket instanceof SSLSocket) {
socket = new NoSSLv3SSLSocket((SSLSocket) socket);
}
return socket;
}

@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return makeSocketSafe(delegate.createSocket(s, host, port, autoClose));
}

@Override
public Socket createSocket(String host, int port) throws IOException {
return makeSocketSafe(delegate.createSocket(host, port));
}

@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
return makeSocketSafe(delegate.createSocket(host, port, localHost, localPort));
}

@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return makeSocketSafe(delegate.createSocket(host, port));
}

@Override
public 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.getSupportedProtocols()));
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);
}
}

但是我遇到了以下异常:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb838faa0: Failure in SSL library, 通常是协议(protocol)错误错误:14077410:SSL 例程:SSL23_GET_SERVER_HELLO:sslv3 警报握手失败(外部/openssl/ssl/s23_clnt.c:741 0x9da83901:0x00000000)

SSL服务只启用了TLSv1.2,SSLv3已被禁用,但应用程序似乎仍在使用sslv3?

最佳答案

我按照文章 http://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/ 中提供的指示解决了这个问题几乎没有变化。

SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
SSLSocketFactory noSSLv3Factory = null;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
noSSLv3Factory = new TLSSocketFactory(sslContext.getSocketFactory());
} else {
noSSLv3Factory = sslContext.getSocketFactory();
}
connection.setSSLSocketFactory(noSSLv3Factory);

这是自定义 TLSSocketFactory 的代码:

public static class TLSSocketFactory extends SSLSocketFactory {

private SSLSocketFactory internalSSLSocketFactory;

public TLSSocketFactory(SSLSocketFactory delegate) throws KeyManagementException, NoSuchAlgorithmException {
internalSSLSocketFactory = delegate;
}

@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}

@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}

@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}

@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}

@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}

@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}

@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}

/*
* Utility methods
*/

private static Socket enableTLSOnSocket(Socket socket) {
if (socket != null && (socket instanceof SSLSocket)
&& isTLSServerEnabled((SSLSocket) socket)) { // skip the fix if server doesn't provide the TLS version
((SSLSocket) socket).setEnabledProtocols(new String[]{TLS_v1_1, TLS_v1_2});
}
return socket;
}

private static boolean isTLSServerEnabled(SSLSocket sslSocket) {
System.out.println("__prova__ :: " + sslSocket.getSupportedProtocols().toString());
for (String protocol : sslSocket.getSupportedProtocols()) {
if (protocol.equals(TLS_v1_1) || protocol.equals(TLS_v1_2)) {
return true;
}
}
return false;
}
}

您还可以使用 https://www.ssllabs.com/ssltest/analyze.html 等在线服务检查服务器证书确保服务器具有您启用的证书

关于Android 4.2.2,如何为 HttpsURLConnection 启用 TLS 1.2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37395321/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com