And*_*Sec 11 java ssl android jsse httpsurlconnection
在TLS协商期间,客户端将支持的密码列表发送到服务器,服务器选择一个密码,然后开始加密.当我HttpsURLConnection
用于通信时,我想更改Android发送到服务器的密码列表.
我知道我可以setSSLSocketFactory
在HttpsURLConnection
对象上使用它来设置它SSLSocketFactory
.当我想要更改由SSLSocket
返回的信任管理器等时,这非常有用SSLSocketFactory
.
我知道一般这个密码组列表可以使用编辑SSLParameters
对象,并将其传递到SSlsocket
或SSLEngine
使用他们提供的方法的对象.
但SSLSocketFactory
似乎没有公开这样的方法!
我找不到一种方法来改变我传递给的创建SSLParameters
的返回SSLSocket
对象.SSLSocketFactory
HttpsURLConnection
该怎么办?
我想这也与Java有关,不仅仅是Android.也许有一种OO方式来做(例如扩展SSLSocketFactory
并提供给它HttpsURLConnection
?)
Thi*_*ris 15
这段代码有点粗糙.请小心使用.
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<String> suitesList = new ArrayList<String>(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<String> suitesList = new ArrayList<String>(Arrays.asList(supportedCipherSuites));
suitesList.remove(PREFERRED_CIPHER_SUITE);
suitesList.add(0, PREFERRED_CIPHER_SUITE);
return suitesList.toArray(new String[suitesList.size()]);
}
}
Run Code Online (Sandbox Code Playgroud)
当你想使用它时.
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();
Run Code Online (Sandbox Code Playgroud)
谢谢.
我将 @ThinkChris 的答案1中的技术捆绑到一个非常简单的方法调用中。在使用Android的HttpsURLConnection
. NetCipher 将HttpsURLConnection
实例配置为使用最受支持的 TLS 版本,删除 SSLv3 支持,并为该 TLS 版本配置最佳密码套件。首先,将其添加到您的build.gradle中:
compile 'info.guardianproject.netcipher:netcipher:1.2'
Run Code Online (Sandbox Code Playgroud)
或者您可以下载netcipher-1.2.jar并将其直接包含在您的应用程序中。然后而不是调用:
HttpURLConnection connection = (HttpURLConnection) sourceUrl.openConnection();
Run Code Online (Sandbox Code Playgroud)
调用这个:
HttpsURLConnection connection = NetCipher.getHttpsURLConnection(sourceUrl);
Run Code Online (Sandbox Code Playgroud)
如果您想专门定制该密码列表,您可以检查那里的代码。但大多数人不应该考虑密码列表,而是应该默认使用常见的最佳实践。
归档时间: |
|
查看次数: |
13464 次 |
最近记录: |