首先我想说我正在探索 SSL socket 的世界并且网上没有那么多资料,我已经浏览了 StackOverflow 上的大部分主题,但我仍然对 TrustManager 的概念感到困惑, keystore 、主机名 validator ... 所以我必须编写一个 Java 客户端(单向 SSL)以使用 SSL 连接某些服务器。 我正在制作三种行为,Android 的原生行为(我相信如果证书不受信任,它不会处理握手)。 一个朴素的,带有一个带有空 checkServerTrusted 函数的自定义 TrustManager。 现在我想使用 HostNameVerfier 来允许所有主机名。 但老实说,我有点迷路了,我已经搜索了好几天,但互联网上没有关于 android ssl 的好资料。 到目前为止,这是我的代码:
Naive custom TrustManager (empty checkServerTrusted)
SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManager trustManagerNaive = new X509TrustManager(){
@Override
public void checkClientTrusted(
X509Certificate[] chain,
String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(
X509Certificate[] chain,
String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
};
sslContext.init(null, new TrustManager[]{trustManagerNaive}, null);
SSLSocketFactory socketFactory = (SSLSocketFactory)sslContext.getSocketFactory();
SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, Integer.parseInt(port_number_et.getText().toString()));
//Native Android behavior (does not accept any untrusted certificate)
SSLSocketFactory socketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, Integer.parseInt(port_number_et.getText().toString()));
最佳答案
这是一个带有“不可信”证书的运行示例:
KeyStore keyStore = KeyStore.getInstance("BKS");
InputStream in = getContext().getAssets().open(Constants.KEYSTORE_FILENAME);
keyStore.load(in, Constants.KEYSTORE_PASSWORD);
in.close();
SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore);
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", socketFactory, 443));
BasicHttpParams basicHttpParams = new BasicHttpParams();
HttpProtocolParams.setVersion(basicHttpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(basicHttpParams, HTTP.UTF_8);
ThreadSafeClientConnManager ccm = new ThreadSafeClientConnManager(basicHttpParams, registry);
httpClient = new DefaultHttpClient(ccm, basicHttpParams);
一些解释:
- 使用不受信任的证书创建 keystore
- 加载 keystore 并在 SSLSocketFactory 中设置它
- 将 hostnameVerifier 设置为 ALLOW_ALL_HOSTNAME_VERIFIER(因为证书不受信任)
然后您可以使用此 httpClient 进行 http 或 https 请求,如下所示:
httpClient.execute(httpGet, new BasicHttpContext());
关于java - Android Java SSL 套接字 - AllowAllHostNameVerifier,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29123106/