使用 httpclient 在 android 中升级到 TLSV1.0 或 1.1 到 TLSV1.2
Upgrade to TLSV1.0 or 1.1 to TLSV1.2 in android using httpclient
我的应用程序现有 运行 tlsv1.0 或 1.1 并想更新 tls 版本 1.2,但仍然显示旧版本 tls1.0 或 tls1.1 未显示 1.2。示例代码:
public class TLSSocketFactoryNew extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactoryNew() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLSv1.2");
TrustManager[] managers = new TrustManager[] { new TrustManagerManipulator() };
context.init(null, managers, new SecureRandom());
internalSSLSocketFactory = context.getSocketFactory();
}
@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 there TLS version
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
}
return socket;
}
private static boolean isTLSServerEnabled(SSLSocket sslSocket) {
System.out.println("isTLSServerEnabled :: " + sslSocket.getSupportedProtocols().toString());
for (String protocol : sslSocket.getSupportedProtocols()) {
if (protocol.equals("TLSv1.1") || protocol.equals("TLSv1.2")) {
return true;
}
}
return false;
}
}
我现在担心的是,我只想让我的应用程序只支持tlsv1.2版本,所有旧版本都应该避免。
我如何在我的实用程序 class 中调用 TLSSocketFactoryNew,仅使用 httpclient- 不需要解决方案okhttp, httpurlconnection.
Util.java
HttpClient mHttpClient= returnHttpClient(httpParams);
并获取 httpclient
private HttpClient returnHttpClient(HttpParams httpParams) {
SchemeRegistry registry = new SchemeRegistry();
try {
registry.register(new Scheme("https", (SocketFactory) new TLSSocketFactoryNew(), 443));
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
HttpClient client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry),httpParams);
return client;
}
我在 Activity、
上的 oncreate 内部添加了这个片段
try {
ProviderInstaller.installIfNeeded(getBaseContext());
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
和依赖项:
compile 'com.google.android.gms:play-services-base:11.0.1'
compile files('libs/commons-codec-1.9.jar')
compile files('libs/commons-logging-1.1.1.jar')
compile files('libs/core-1.51.0.0.jar')
// compile files('libs/httpclient-4.0.1.jar')
compile files('libs/httpcore-4.0.1.jar')
compile files('libs/jackson-core-2.7.2.jar')
compile files('libs/jsonic-1.3.0.jar')
我在这里提出一点,将我的 tls 版本升级到 v1.2 是错误的,我的代码中是否遗漏了什么?
提前致谢。
首先确保您使用的任何机器 运行 都启用了 TLS 1.2。
设置 SSLContext:
SSLContext sslContext = SSLContextBuilder.create().useProtocol("TLSv1.2").build();
然后使用 HttpClientBuilder 构建您的 HttpClient:
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setSSLContext(sslContext);
我这会对你有所帮助,完全相同的问题,我通过以下片段解决了:
只需获取 HttpClient:
private HttpClient getHttpClient(HttpParams httpParams) {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
SSLSocketFactory delegate = null;
delegate = new TLSSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultSSLSocketFactory(delegate);
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
HttpClient httpclient = new DefaultHttpClient(httpParams);
httpclient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", socketFactory, 443));
return httpclient;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
和TLSSocketFactory.java文件应该是
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class TLSSocketFactory extends SSLSocketFactory {
private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
final SSLSocketFactory delegate;
public TLSSocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
}
return s;
}
}
如果您想了解更多信息,请访问以下链接:
https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/
https://medium.com/tech-quizlet/working-with-tls-1-2-on-android-4-4-and-lower-f4f5205629a
我的应用程序现有 运行 tlsv1.0 或 1.1 并想更新 tls 版本 1.2,但仍然显示旧版本 tls1.0 或 tls1.1 未显示 1.2。示例代码:
public class TLSSocketFactoryNew extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactoryNew() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLSv1.2");
TrustManager[] managers = new TrustManager[] { new TrustManagerManipulator() };
context.init(null, managers, new SecureRandom());
internalSSLSocketFactory = context.getSocketFactory();
}
@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 there TLS version
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
}
return socket;
}
private static boolean isTLSServerEnabled(SSLSocket sslSocket) {
System.out.println("isTLSServerEnabled :: " + sslSocket.getSupportedProtocols().toString());
for (String protocol : sslSocket.getSupportedProtocols()) {
if (protocol.equals("TLSv1.1") || protocol.equals("TLSv1.2")) {
return true;
}
}
return false;
}
}
我现在担心的是,我只想让我的应用程序只支持tlsv1.2版本,所有旧版本都应该避免。
我如何在我的实用程序 class 中调用 TLSSocketFactoryNew,仅使用 httpclient- 不需要解决方案okhttp, httpurlconnection.
Util.java
HttpClient mHttpClient= returnHttpClient(httpParams);
并获取 httpclient
private HttpClient returnHttpClient(HttpParams httpParams) {
SchemeRegistry registry = new SchemeRegistry();
try {
registry.register(new Scheme("https", (SocketFactory) new TLSSocketFactoryNew(), 443));
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
HttpClient client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry),httpParams);
return client;
}
我在 Activity、
上的 oncreate 内部添加了这个片段try {
ProviderInstaller.installIfNeeded(getBaseContext());
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
和依赖项:
compile 'com.google.android.gms:play-services-base:11.0.1'
compile files('libs/commons-codec-1.9.jar')
compile files('libs/commons-logging-1.1.1.jar')
compile files('libs/core-1.51.0.0.jar')
// compile files('libs/httpclient-4.0.1.jar')
compile files('libs/httpcore-4.0.1.jar')
compile files('libs/jackson-core-2.7.2.jar')
compile files('libs/jsonic-1.3.0.jar')
我在这里提出一点,将我的 tls 版本升级到 v1.2 是错误的,我的代码中是否遗漏了什么?
提前致谢。
首先确保您使用的任何机器 运行 都启用了 TLS 1.2。
设置 SSLContext:
SSLContext sslContext = SSLContextBuilder.create().useProtocol("TLSv1.2").build();
然后使用 HttpClientBuilder 构建您的 HttpClient:
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setSSLContext(sslContext);
我这会对你有所帮助,完全相同的问题,我通过以下片段解决了:
只需获取 HttpClient:
private HttpClient getHttpClient(HttpParams httpParams) {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
SSLSocketFactory delegate = null;
delegate = new TLSSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultSSLSocketFactory(delegate);
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
HttpClient httpclient = new DefaultHttpClient(httpParams);
httpclient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", socketFactory, 443));
return httpclient;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
和TLSSocketFactory.java文件应该是
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class TLSSocketFactory extends SSLSocketFactory {
private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
final SSLSocketFactory delegate;
public TLSSocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
}
return s;
}
}
如果您想了解更多信息,请访问以下链接:
https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/
https://medium.com/tech-quizlet/working-with-tls-1-2-on-android-4-4-and-lower-f4f5205629a