欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android开发中的Https安全规范

程序员文章站 2022-07-07 18:36:23
...

前言:

越来越多的Android应用为了android通信安全,将http通信改为Https通信连接,或单向验证或双向验证。 但是如果不按规范将TLS连接中对证书等进行安全校验,实际上和http通信没有任何差别,还是有很多的安全风险,如中间人攻击等。
一方面TLS版本要高,如TLS1.2、TLS1.3,因为旧版本的都已发现安全漏洞。另外,就是一些通用部分,如下为阿里Android开发手册部分提到的规范,可以进行参考。

从 2017 年 3 月 1 日起,只要新应用或应用更新采用的 HostnameVerifier 的实施方式不安全,一律禁止在 Google Play 发布。您已发布的APK版本不会受到影响,但是,如果不解决此漏洞,您将无法为应用发布任何更新。

使用HostnameVerifier验证主机名

【强制】在实现的 HostnameVerifier 子类中,需要使用 verify 函数效验服务器主机名的合法性,否则会导致恶意程序利用中间人攻击绕过主机名效验。
说明:
在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。如果回调内实现不恰当,默认接受所有域名,则有安全风险。
反例:

HostnameVerifier hnv=new HosernameVerifier(){
  @Override
  public boolean verify(String hostname,SSLSession session){
      return ture;
  }
}
HttpsURLConnection.setDefaultHostnameVerifier(hnv);

正例:

正例:
HostnameVerifier hnv=new HosernameVerifier(){
@Override
public boolean verify(String hostname,SSLSession session){
    if("youhostname".equals(hostname)){
        return true;
    }else{
          HostnameVerifier        hv=HttpsURLConnection.getDefaultHostnameVerifier();
         return hv.verify(hostname,session);
          }
  }
}

使用checkServerTrusted验证服务端证书合法性

【强制】利用 X509TrustManager 子类中的 checkServerTrusted 函数效验服务器端证书的合法性。
说明:
在实现的 X509TrustManager 子类中未对服务端的证书做检验,这样会导致不被信任的证书绕过证书效验机制。正确做法应该在checkServerTrusted函数中对服务端证书合法性、有效性进行校验。
反例:

TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType)
	throws CertificateException {
	//do nothing,接受任意客户端证书
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
	throws CertificateException {
	//do nothing,接受任意服务端证书
}
public X509Certificate[] getAcceptedIssuers() {
	return null;
	}
};
sslContext.init(null, new TrustManager[] { tm }, null);

使用严格模式验证策略

【强制】 Android APP 在 HTTPS 通信中,验证策略需要改成严格模式。 说明: Android APP 在 HTTPS 通信中,使用 ALLOW_ALL_HOSTNAME_VERIFIER,表示允许和所有的 HOST 建立 SSL 通信,这会存在中间人攻击的风险,最终导致敏感信息可能会被劫持,以及其他形式的攻击。
反例:

SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

ALLOW_ALL_HOSTNAME_VERIFIER 关闭 host 验证,允许和所有的 host 建立SSL 通信,BROWSER_COMPATIBLE_HOSTNAME_VERIFIER 和浏览器兼容的验证策略,即通配符能够匹配所有子域名 ,STRICT_HOSTNAME_VERIFIER 严格匹配模式,hostname 必须匹配第一个 CN 或者任何一个 subject-alts,以上例子使用了 ALLOW_ALL_HOSTNAME_VERIFIER,需要改成 STRICT_HOSTNAME_VERIFIER