| 
                         Apache http client  因为从api23起被Android抛弃,因此使用率较低。目前更多使用的是HttpURLConnection类或第三方库OKhttp3.0进行HTTPS通信。其中OKhttp3.0的部分运用与HttpURLConnection相同,客户端都可以通过实现X509TrustManager接口的checkServerTrusted方法,将服务器证书与APP预埋证书做对比,来完成强校验。此外,也可以再通过实现HostnameVerifier接口的verify方法,校验服务器证书中的一般名称(CN)是否与域名相符。通过使用上述方法,完成客户端对服务端的证书强校验。 
(2) 应用分析 
由于这次是自编译的文件,就不通过APK反编译等方法查看代码了,直接看主要通信类HttpClientSslHelper的源码。 
- public class HttpClientSslHelper { 
 -     public static boolean isServerTrusted1 = true;  //强校验关键参数 
 -     private static SSLContext sslContext = null; 
 -     public static OkHttpClient getSslOkHttpClient(Context context) { 
 -         OkHttpClient.Builder builder = new OkHttpClient.Builder(); 
 -         builder.sslSocketFactory(getSslContextByCustomTrustManager(context).getSocketFactory()) 
 -                 .hostnameVerifier(new HostnameVerifier() { 
 -                     @Override  //实现自定义的HostnameVerifier 对象的verify校验方法 
 -                     public boolean verify(String hostname, SSLSession session) { 
 -                         Log.d("HttpClientSslHelper", "hostname = " + hostname); 
 -                         if ("192.168.96.1".equals(hostname)) { 
 -                             //根据isServerTrusted1的值进行校验,若为True,则校验成功,执行后续连接 
 -                             return isServerTrusted1; 
 -                         } else { 
 -                             //由于是实验环境,if语句总为真,不会执行else语句 
 -                             HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); 
 -                             return hv.verify("localhost", session); 
 -                         } 
 -                     } 
 -                 }); 
 -         return builder.build(); 
 -     } 
 -  
 -     public static SSLContext getSslContextByCustomTrustManager(Context context) { 
 -         if (sslContext == null) { 
 -             try { 
 -                 CertificateFactory cf = CertificateFactory.getInstance("X.509","BC"); 
 -                 InputStream caInput = new BufferedInputStream(context.getResources().getAssets().open("server.cer")); 
 -                 final Certificate ca; 
 -                 try { 
 -                     ca = cf.generateCertificate(caInput); 
 -                 } finally { 
 -                     caInput.close(); 
 -                 } 
 -                 sslContext = SSLContext.getInstance("TLS"); 
 -                 //自定义X509TrustManager接口的checkClientTrusted、checkServerTrusted和getAcceptedIssuers方法 
 -                 sslContext.init(null, new X509TrustManager[]{new X509TrustManager() { 
 -                     public void checkClientTrusted(X509Certificate[] chain, 
 -                                                    String authType) throws CertificateException { 
 -                         Log.d("HttpClientSslHelper", "checkClientTrusted --> authType = " + authType); 
 -                         //校验客户端证书 
 -                     } 
 -  
 -                     public void checkServerTrusted(X509Certificate[] chain, 
 -                                                    String authType) throws CertificateException { 
 -                         Log.d("HttpClientSslHelper", "checkServerTrusted --> authType = " + authType); 
 -                         //校验服务器证书 
 -                         for (X509Certificate cert : chain) { 
 -                             cert.checkValidity(); 
 -                             try { 
 -                                  //关键点,用APP中内置的服务端证书server.cer来校验网络连接中服务器颁发的证书 
 -                                 cert.verify(ca.getPublicKey()); 
 -                             } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) { 
 -                                 e.printStackTrace(); 
 -                                 //校验失败,则更改isServerTrusted1值为false 
 -                                 isServerTrusted1 = false; 
 -                             } 
 -                         } 
 -                     } 
 -  
 -                     public X509Certificate[] getAcceptedIssuers() { 
 -                         return new X509Certificate[0]; 
 -                     } 
 -                 }}, null); 
 -             } catch (Exception e) { 
 -                 e.printStackTrace(); 
 -             } 
 -         } 
 -         return sslContext; 
 -     } 
 - } 
 
  
由上可知,将HttpClientSslHelper类的getSslContextByCustomTrustManager方法重写,重新实现checkServerTrusted方法,让其不修改isServerTrusted1的值,即可绕过证书强校验。 
(3) 开始Hook 
重新实现checkServerTrusted方法                         (编辑:91站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |