通过 Network Security Configuration
,能让app定制网络安全设置, 并且这些配置不需要你改代码,只需要加上配置文件即可。
它主要包括如下特性
-
Custom trust anchors
自定义用于app安全链接的可信任证书(CA)。例如,让app信任特定的自签名证书,或者某些限定的公共签名中心的签名。
-
Debug-only overrides
可以在一个app应用中安全地调试安全连接,而不会给已安装的基准版本增加风险。
-
Cleartext traffic opt-out
防止app使用明文进行交互。
-
Certificate pinning
限定app只使用特定的证书进行安全连接。
添加安全配置文件
Network Security Configuration
特性使用一个XML文件,来描述你的app应用设置。你必须在你app的manifest中包含一个记录,来包含这个xml文件。如下:
...
自定义可信任证书
一个app应用可能不是采用平台默认的配置,而是会使用一系列自定义的可信任证书(CA),这样做的主要原因:
- app应用可能会使用一个自定义的证书授权连接到主机。例如自签名CA证书,或者一个公司内部发行的CA证书。
- 可能会需要限制app应用所信任的CA集合,而非信任所有预安装好的CA证书。
- app应用可能会信任一些额外的、在系统中没有被包含的证书。
默认来说,所有app应用的安全连接(使用类似TLS和HTTPS协议)信任所有系统预先安装好的CA证书;并且在Android 6.0(API level是23)以及更低版本的的app应用中,也默认信任用户自行添加存储的CA证书。应用程序可以使用 base-config
(用于 app-wide
定制), 或 domain-config
(用于 per-domain
定制), 来自定义它所拥有的连接。
配置自定义CA
假设你想要链接到你的主机上,这个主机使用自签名的SSL证书,或者使用一个非公共签名机制签发的、但是你信任的SSL证书CA(比如你公司内部的CA),
那么需要配置 res/xml/network_security_config.xml
文件内容如下:
example.com
然后根据文件内容,添加一个 PEM
或者 DER
格式的自定义或者非公共CA证书到 res/raw/my_ca
。
限制可信任的CA证书集
一个app应用可能不想信任所有系统提供的CA集,而只使用它自己信任的一套CA子集。这样可以保护app防止它被其他任何CA别的证书所欺骗。
限制可信任的CA证书集的配置类似配置一个指定域的自定义CA证书,不同点在于需要在资源中提供多个CA证书。
那么配置 res/xml/network_security_config.xml
文件内容如下:
secure.example.com
cdn.example.com
这里需要用 PEM
或者 DER
格式添加信任的CA证书到 res/raw/trusted_roots
。并且需要注意的是,如果使用 PEM
格式,那么文件必须只包含 PEM
数据,不能有额外的文本。你也可以提供多个
元素,而非只用一个。
信任额外的CA证书
一个app应用可能会想要信任不在系统中的额外的应用。这可能是因为系统没有包含这个CA证书,或者这个CA证书不符合被包含入Android系统的要求。app应用程序可以通过指定多个证书源,来配置这个CA证书。
res/xml/network_security_config.xml
如下:
Configuring CAs for Debugging
当调试一个使用https连接的应用程序的时候,你可能会想要连接到一个本地的开发服务器上,这个服务器没有像你产品服务器那样的SSL认证。为了不修改应用程序代码而支持这个功能,你可以指定一个 debug-only
的CA证书,这个证书只有在使用 debug-overrides
中的属性 android:debuggable
为 true
的时候是可信的。通常来说,IDE和编译工具会为非发布版本的编译自动设置这个选项。
这个方式要比通常使用条件代码的方式安全,因为出于安全性的考虑,app应用市场不接收被标记为debuggable的应用程序。
配置文件 res/xml/network_security_config.xml
内容如下:
Opting Out of Cleartext Traffic
应用程序如果仅通过安全连接连接到目标,就会导致对清流目标(使用非加密的htpp协议替代https的目标)的不支持。这个选项可以帮助阻止app应用中,由于外部源(如backend服务器)提供的URLs变化,导致某些意外的regression。 可以查看 NetworkSecurityPolicy.isCleartextTrafficPermitted()
了解更详细的内容。
例如,一个应用程序可能想要保证所有链接到 secure.example.com
的连接都是通过 HTTPS链接的,以便保护从主机网络中进行的敏感数据传输。
我们可以修改 res/xml/network_security_config.xml
如下:
secure.example.com
Pinning Certificates
通常来说,一个app应用信任所有预先安装的CA证书。如果这些证书中任何一个具有欺诈行为,那么app应用将会面临劫持攻击的风险。有些app应用可以选择受限的证书集合(通过限制可信证书集或者使用证书pinning)。
证书的pinning通过公钥哈希提供一系列的证书来实现。一个认证链只有在认证链包含至少一个pinned的公钥的之后,才被认为是合法的。
我们需要注意的是,当使用认证pinning的时候,你可以一直包含一个backup key,这样如果你不得不切换新key或者修改CA认证(当pinning到一个CA证书或者那个CA的中间者)的时候,你的应用程序连接不会受到影响。否则,你将必须修改app使得它能够恢复连接。
另外,你也可以为pins设置一个过期时间,这样过了那个时间之后,pinning将会不起作用。这个有助于规避一些在未更新的app应用中的连通问题。然而,为pins设置过期时间,可能会导致pinning被忽略。
res/xml/network_security_config.xml
example.com
7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=
fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=
Configuration Inheritance Behavior
如果值没有在指定的配置中设置,那么将会是继承而来的。这样就可以在保持配置文件可读的情况下,允许更复杂的配置。
如果一个值没有在特定的entry中被设置,那么这个值会从更通用的entry中继承过来。比如,没有在 domain-config
中被设置的值,将从它所嵌入的父亲的 domain-config
中继承过来,如没有嵌入的父亲,那么将从 base-config
中集成。如果在 base-config
中也没有设置该值,那会使用平台默认值。
比如:考虑所有到 example.com
子域的连接,必须使用自定义的CA证书集合。另外,允许在除了 secure.example.com
的域上进行清流( cleartext
)传输。我们将 secure.example.com
嵌入到 example.com
的配置中,就不用为它重复配置其它信任的内容了。
配置文件 res/xml/network_security_config.xml
如下:
example.com
secure.example.com
Configuration File Format
完整的例子:
...
android.com
...
...
...
...
...
...
可以包括:
- 0或1个
- 任何数目的
- 0或1个
格式:
...
可以包括:
格式:
...
可以包括:
- 1或多个
- 0或1个
- 0或1个
- 任何数目嵌入的
格式:
example.com
格式:
...
可以包括:
0或1个
格式:
...
可以包括:
任何数目的
格式:
格式:
...
可以包括:
任何数目的
格式:
base64 encoded digest of X.509
SubjectPublicKeyInfo (SPKI)
参考资料
http://www.cnblogs.com/lzl-sml/p/5294462.html
能让app定制网络安全设置:
+ Debug-only overrides(自定义信用的CA)。
+ Debug-only overrides(自定义能调试你app信用的CA)
+ Cleartext traffic opt-out(防止网络请求明文交互)
+ Certificate pinning(自定义只信用包含特定公钥CA)
这个特性,对于支付类软件、金融类和购物类等是福音啊,防止劫持,防止重定向。
这些配置不需要你改代码,只需要加上配置文件即可。
http://www.tuicool.com/articles/f6zaqmf
https://developer.android.com/preview/features/security-config.html
https://developer.android.com/guide/components/fundamentals.html#Components
http://www.vogella.com/tutorials/AndroidLifeCycle/article.html
https://developer.android.com/guide/topics/processes/process-lifecycle.html
https://developer.android.com/guide/components/activities.html
https://developer.android.com/training/basics/activity-lifecycle/index.html
https://developer.android.com/reference/android/content/BroadcastReceiver.html#ProcessLifecycle
https://developer.android.com/reference/android/app/Service.html#ServiceLifecycle