在android sdk level 23中SSLParameter.setServerNames的替代方法是什么?
问题描述:
我正在使用SSLSocket连接到服务器。我想使用ssl SNI扩展。我可以在java中使用SSLParameter.setServerNames
。但它出现在android它不可用,直到sdk 24.我在这里有什么选择?在android sdk level 23中SSLParameter.setServerNames的替代方法是什么?
答
我有同样的问题,通过使用反射解决。 使用连接插座:
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) sf.createSocket(uri.getHost(), 443);
setSNIHost(sf, socket, uri.getHost());
SSLSession s = socket.getSession();
其中setSNIHost声明为:
public void setSNIHost(final SSLSocketFactory factory, final SSLSocket socket, final String hostname) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
Log.i(TAG, "Setting SNI via SSLParameters");
SNIHostName sniHostName = new SNIHostName(hostname);
SSLParameters sslParameters = socket.getSSLParameters();
List<SNIServerName> sniHostNameList = new ArrayList<>(1);
sniHostNameList.add(sniHostName);
sslParameters.setServerNames(sniHostNameList);
socket.setSSLParameters(sslParameters);
} else if (factory instanceof android.net.SSLCertificateSocketFactory) {
Log.i(TAG, "Setting SNI via SSLCertificateSocketFactory");
((android.net.SSLCertificateSocketFactory)factory).setHostname(socket, hostname);
} else {
Log.i(TAG, "Setting SNI via reflection");
try {
socket.getClass().getMethod("setHostname", String.class).invoke(socket, hostname);
} catch (Throwable e) {
Log.e(TAG, "Could not call SSLSocket#setHostname(String) method ", e);
}
}
}
我真的不记得在那里我复制了反射的代码,我只是增加了24 API支持。