在Android中使用HTTPS请求时,如果我们的应用需要连接到信任的服务器,但该服务器的SSL证书并不能得到Android系统的信任,那么就需要在我们的应用中跳过SSL证书的验证流程,实现信任所有证书。
以下是一个跳过所有SSL证书验证的示例代码:
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient httpClient = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(httpClient.getParams(), registry);
DefaultHttpClient client = new DefaultHttpClient(mgr, httpClient.getParams());
// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
但是,这种方式存在一定的安全风险,因为它信任所有的SSL证书,包括伪造的证书。所以在生产环境中,并不推荐使用。
更好的做法是使用SSL证书白名单来对信任的服务器主机进行接受。具体步骤如下:
- 把服务器的公共证书以.cer格式保存在应用的asset目录中。
-
在代码中添加一个新的SSLSocketFactory,并使用.cer文件创建一个新的TrustManager。这个TrustManager只会信任.asset目录下的证书:
SSLContext context = SSLContext.getInstance("TLS"); CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream caInput = new BufferedInputStream(getAssets().open("yancheng.cer")); Certificate ca = cf.generateCertificate(caInput); KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); keystore.load(null, null); keystore.setCertificateEntry("ca", ca); String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keystore); context.init(null, tmf.getTrustManagers(), null); SSLSocketFactory sockFact = context.getSocketFactory(); client.setSSLSocketFactory(sockFact);
- 设置DefaultHttpClient使用这个新的SSLSocketFactory。
以上代码得到的client就可以用于执行https请求了,而且只信任.asset目录下的证书。мож以在请求的时候设置白名单。具体实现方式可能会因实际情况和业务需求有所不同,具体实现时需商量确定。
阿里云提供了一种白名单配置方式,可以过滤HTTPS请求证书。Android设备需要进行如下操作才能进行HTTPS请求:
- 创建您自己的自定义信任管理器类。您需要实现X509TrustManager接口,并在checkServerTrusted方法中添加自己的逻辑代码。此代码将会在每次HTTPS连接时被调用,因此您要添加的代码就是过滤证书的代码。
- 使用SocketFactory设置你的自定义信任管理器类。在创建HTTPS连接时,需要用到SSLSocketFactory。您可以创建自己的SSLSocketFactory,并把它设置为默认的SSLSocketFactory。
- 修改系统信任的证书库。默认的信任管理器会使用系统自带的证书库。为了让你的自定义信任管理器工作,您需要创建自己的证书库,并把它设置为系统默认的证书库。
关于让Android HTTPS请求过滤白名单代码示例代码如下:
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return hostname.equals("your_whiteListed_domain.com");
}
});
以上代码在创建HTTPS连接时会检查服务器的主机名是否在白名单上,只有在白名单上的主机名才会被信任。
最后一步就是在你的代码里使用你的自定义SSLSocketFactory创建HTTPS连接。现在,只有白名单上的证书才会被信任,其他一切都会被过滤掉。
发布者:luotuoemo,转转请注明出处:https://www.jintuiyun.com/166896.html