我在谷歌播放中使用了一个应用程序,我收到了来自谷歌的邮件说:
此电子邮件末尾列出的您的应用使用接口X509TrustManager的不安全实现。具体而言,在与远程主机建立HTTPS连接时,该实现会忽略所有SSL证书验证错误,从而使您的应用容易受到中间人攻击。
要正确处理SSL证书验证,请在自定义X509TrustManager接口的checkServerTrusted方法中更改代码,以便在服务器提供的证书不符合您的期望时引发CertificateException或IllegalArgumentException。
我的应用使用“https”,我的checkServerTrusted()
如下:
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
然后我修改了这个功能:
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
if (chain == null) {
throw new IllegalArgumentException("checkServerTrusted: X509Certificate array is null");
}
if (!(chain.length > 0)) {
throw new IllegalArgumentException("checkServerTrusted: X509Certificate is empty");
}
if (!(null != authType && authType.equalsIgnoreCase("RSA"))) {
throw new CertificateException("checkServerTrusted: AuthType is not RSA");
}
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
自定义SSLSocketFactory:
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore ctx) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(ctx);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[]{tm}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
HttpClient函数:
private static HttpClient getHttpClient(int timeout) {
if (null == mHttpClient) {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params,
HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
ConnManagerParams.setTimeout(params, timeout);
HttpConnectionParams.setConnectionTimeout(params, timeout);
HttpConnectionParams.setSoTimeout(params, timeout);
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
schReg.register(new Scheme("https", sf, 443));
ClientConnectionManager conManager = new ThreadSafeClientConnManager(
params, schReg);
mHttpClient = new DefaultHttpClient(conManager, params);
} catch (Exception e) {
e.printStackTrace();
return new DefaultHttpClient();
}
}
return mHttpClient;
}
但是我对此并不了解,我只是通过电子邮件说的修改我的代码,我想我还没有解决这个问题。这个警告到底是什么?怎么解决?
答案 0 :(得分:1)
您提出的修改不会修复安全漏洞。无论有效性如何,您的代码仍将接受任何格式正确的证书。
如果您不确定如何正确验证证书,则应该删除自定义信任管理器。除非你做一些与众不同的事情,否则你不需要一个。
答案 1 :(得分:0)
最简单的方法是不提供自己的自定义TrustManager
。只需使用默认的TrustManager
,它将为您执行公钥( X.509 )验证和验证。
答案 2 :(得分:0)
仅使用默认的 X509trustmanager 方法 checkServerTrusted(chain, authType),它们将适当地处理所有验证。