Network Security Config
当我们使用Fiddler等工具抓包的时候,我们往往需要在设备上面安装一个证书,这样我们才能抓取https的数据,类似于中间人攻击,抓包工具使用自己的证书去加解密,如果客户端没有对证书进行校验的话,那么就无法防范这种情况。但是在Android 7.0(sdk>=24)以后,如果你的targetSdkVersion>=24,那么默认是只能使用系统的CA,这样我们就无法使用Fiddler等工具进行抓包。
当我们第一次开始请求后台数据,查看log可以看到 No Network Security Config specified, using platform default。
系统默认行为
targetSdkVersion>=24 如果没有额外配置,默认只信任系统CA,如果我们使用Fiddler抓包,会提示CertPathValidatorException,因为Fiddler的证书是我们自己安装的
targetSdkVersion < 24 默认信任系统上面安装的CA。包括用户自己安装的,Network Security Config配置无效
自定义配置
1、在xml文件夹下创建一个network_security_config.xml文件(名字可自定义)
2、在application标签下进行配置
<manifest ... >
<application
android:networkSecurityConfig="@xml/network_security_config"
... >
...
</application>
</manifest>
配置规则
1、大致模板
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config>
<domain includeSubdomains="true">android.com</domain>
<trust-anchors>
<!--自定义的证书-->
<certificates src="@raw/my_ca" />
</trust-anchors>
<pin-set>
<pin digest="SHA-256">base64 encoded digest of X.509
SubjectPublicKeyInfo (SPKI)
</pin>
</pin-set>
</domain-config>
<!--DEBUG调试时采用的信任源,只在DEBUG时起作用。-->
<debug-overrides>
<trust-anchors>
<!--信任用户安装的证书-->
<certificates src="user" />
<!--信任系统预装的证书-->
<certificates src="system" />
</trust-anchors>
</debug-overrides>
</network-security-config>
2、
base-config是默认的配置,当domain-config一个都不匹配的时候,使用base-config
cleartextTrafficPermitted:是否允许明文传输
<base-config cleartextTrafficPermitted=["true" | "false"]>
...
</base-config>
3、trust-anchors
用于表示被信任的证书集合
<trust-anchors>
...
</trust-anchors>
4、certificates
用来表示一个X.509证书
<certificates src=["system" | "user" | "raw resource"]
overridePins=["true" | "false"] />
src: CA 证书的来源。每个证书可为下列状态之一
指向包含 X.509 证书的文件的原始资源 ID。证书必须以 DER 或 PEM 格式编码。如果为 PEM 证书,则文件不得包含额外的非 PEM 数据,例如注释。
用系统自带 CA 证书的 “system”
用于用户安装的 CA 证书的 “user”
自定义证书:PEM 或 DER 格式的 CA 证书添加到 res/raw/my_ca
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">example.com</domain>
<trust-anchors>
<certificates src="@raw/my_ca"/>
</trust-anchors>
</domain-config>
</network-security-config>
5、domain-config
配置具体的域名,使用domain 标签声明域名,可以有多个,使用trust-anchors标签声明信任的CA集合,domain-config下面只能有一个trust-anchors
<domain-config cleartextTrafficPermitted=["true" | "false"]>
...
</domain-config>
6、domain
定义一个域名,includeSubdomains是否包含子域名,
<domain includeSubdomains=["true" | "false"]>android.com</domain>
pin-set与pin不做讨论。更多详情可以查看官方文档
7、其他
通过上面我们可以知道,base-config与domain-config都有一个属性cleartextTrafficPermitted,它代表的含义为是否允许进行明文传输(http),当设置为flase的时候,会直接报错,请求失败。
其他
最后还是再说一句,由于网络安全性配置是7.0的新增特性,所以7.0以下配置了也是无效的!!!!
参考链接
https://developer.android.com/training/articles/security-config?hl=zh-cn#domain-config
https://iacn.me/2018/03/14/network-security-configuration-newer-than-android-n/