我已经尝试了几天,想知道如何从服务器获取证书。我们正在进行SSL通信,为了识别服务器,我需要检查它的认证。关于代码的一些事情,我正在使用HttpClient,并且我不想将证书创建为密钥库并添加到“信任库”中,如this链接和许多其他建议所示。所以,为了获得证书,我实现了X509HostnameVerifier,并在其verify()方法中执行以下操作:
session.getPeerCertificates();
但该函数抛出异常:
An exception occurred: javax.net.ssl.SSLPeerUnverifiedException
这里是代码:
import java.io.IOException;
import java.security.cert.Certificate;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
public class MyHostnameVerifier implements ch.boye.httpclientandroidlib.conn.ssl.X509HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
Certificate[] certificates;
try {
certificates = session.getPeerCertificates();
// if connection doesn't contain any certificate - drop it, it might be an hacker.
if (certificates == null || certificates.length == 1)
return true;
} catch (SSLPeerUnverifiedException e) {
}
return true;
}
@Override
public void verify(String hostname, SSLSocket socket) throws IOException {
socket.getSession().getPeerCertificates(); // exception
}
@Override
public void verify(String hostname, String[] arg1, String[] arg2) throws SSLException {
}
@Override
public void verify(String arg0, java.security.cert.X509Certificate arg1) throws SSLException {
}
}
和使用示例:
PoolingClientConnectionManager cm = new PoolingClientConnectionManager();
// Increase max total connection to 10
cm.setMaxTotal(GlobalConstants.HTTP_CLIENT_MAX_TOTAL_CONNECTIONS);
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = CONNECTION_TIMEOUT_MS_DEFAULT;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HostnameVerifier hostnameVerifier = new MyHostnameVerifier();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
cm.getSchemeRegistry().register(new ch.boye.httpclientandroidlib.conn.scheme.Scheme("https", 443, socketFactory));
DefaultHttpClient httpClient = new DefaultHttpClient(cm, httpParameters);
TrustManager
。当调用TrustManager
方法时,服务器的证书会被提供。 - jww