29、Android安全前沿技术:TLS 1.3特性、Certificate Transparency、HTTP/2安全特性
聊到Android安全的前沿技术,我脑子里第一个蹦出来的就是TLS 1.3。说实话,这玩意儿刚出来那会儿,我还在用TLS 1.2做证书绑定,觉得够用了。直到有一次,我在分析一个金融App的流量时,发现它居然还在用TLS 1.0——嗯,那感觉就像看到有人还在用Windows 95一样。
今天咱们就掰开揉碎了聊聊这三个东西:TLS 1.3到底快在哪、Certificate Transparency怎么帮你揪出假证书、以及HTTP/2在安全上挖了哪些坑又填了哪些坑。
TLS 1.3:握手更快,也更安全
先说说TLS 1.3。你想想看,TLS 1.2的握手要来回两次,总共2-RTT(Round Trip Time)。而TLS 1.3呢?一次就够了,1-RTT。如果你用上了0-RTT模式,那连第一次握手都省了。
我在项目中遇到过一个问题:一个视频App在弱网环境下,TLS握手耗时占了总连接时间的60%以上。换成TLS 1.3后,这个比例降到了30%左右。用户体验提升很明显。
但TLS 1.3不只是快。它砍掉了很多不安全的加密套件。比如RSA密钥交换、CBC模式的对称加密,这些在TLS 1.3里全没了。说白了,就是帮你做了一次安全减法。
核心变化:
- 握手从2-RTT降到1-RTT(0-RTT可选)
- 移除了RSA密钥交换、CBC模式、RC4、3DES等
- 只支持前向安全的密钥交换(ECDHE、DHE)
- 加密握手消息(防止中间人篡改协商过程)
在Android上启用TLS 1.3其实很简单。从Android 10(API 29)开始,系统默认就支持了。你只需要确保你的SSLSocket或OkHttp配置正确就行。
// OkHttp 4.x 默认支持 TLS 1.3
val client = OkHttpClient.Builder()
.connectionSpecs(listOf(
ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_3, TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_AES_128_GCM_SHA256,
CipherSuite.TLS_AES_256_GCM_SHA384,
CipherSuite.TLS_CHACHA20_POLY1305_SHA256
)
.build()
))
.build()
避坑指南:我曾经在某个项目里直接用了ConnectionSpec.COMPATIBLE_TLS,结果发现它默认包含了TLS 1.0。后来我改成MODERN_TLS,才把那些老旧的协议版本过滤掉。建议你明确指定支持的TLS版本,别偷懒。
Certificate Transparency:让假证书无处遁形
Certificate Transparency(CT)这个概念,说白了就是给SSL证书加了个公开的“出生证明”。
为什么会需要这个?你想想看,CA(证书颁发机构)也可能被攻破,或者被恶意利用。比如2011年DigiNotar事件,攻击者伪造了Google的证书。如果没有CT,你根本不知道这个证书是不是被偷偷签发的。
CT的工作原理是这样的:CA签发证书时,必须把证书提交到公开的日志服务器。日志服务器返回一个SCT(Signed Certificate Timestamp)。浏览器或App在验证证书时,会检查这个SCT。如果证书没有SCT,或者SCT无效,那就说明这个证书可能有问题。
在Android上,从Android 7.0(API 24)开始,系统就内置了CT验证。但默认只对Google自家的服务启用。如果你想对自己的App启用CT,需要自己实现。
// 使用 okhttp 配合 CertificateTransparencyInterceptor
// 需要引入依赖:com.squareup.okhttp3:okhttp-tls
val certificatePinner = CertificatePinner.Builder()
.add("api.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
注意:CT不是证书绑定的替代品。它们是互补的。证书绑定是硬编码信任某个证书,CT是验证证书是否被公开记录。我建议你两个都用上。
HTTP/2安全特性:多路复用下的新挑战
HTTP/2带来了很多好东西,比如多路复用、头部压缩、服务器推送。但安全方面呢?
首先,HTTP/2强制要求使用TLS(虽然规范里说可以不用,但所有主流浏览器都要求TLS)。这意味着你的HTTP/2连接天然就是加密的。
但多路复用也带来了新的攻击面。比如“HTTP/2 Rapid Reset”攻击,就是利用流重置机制来耗尽服务器资源。我在去年处理过一个案例,一个电商App的API网关被这种攻击打挂了,排查了半天才发现是HTTP/2的流管理出了问题。
| 特性 | 安全影响 | 防范措施 |
|---|---|---|
| 多路复用 | 流重置攻击、并发流耗尽 | 限制最大并发流数、监控流重置频率 |
| 头部压缩(HPACK) | CRIME/BREACH类攻击 | 禁用敏感信息在头部传输、使用随机化 |
| 服务器推送 | 推送资源可能被滥用 | 限制推送资源大小、验证推送来源 |
| 二进制分帧 | 帧注入、协议混淆 | 严格校验帧格式、使用白名单 |
在Android上使用HTTP/2,OkHttp是首选。它默认支持HTTP/2,而且会自动协商协议版本。
// OkHttp 默认启用 HTTP/2
// 你可以通过协议列表来控制
val client = OkHttpClient.Builder()
.protocols(listOf(Protocol.HTTP_2, Protocol.HTTP_1_1))
.build()
我的建议:如果你在Android上使用HTTP/2,一定要设置maxConcurrentStreams。默认值可能太高,容易被攻击。我一般设成100左右,根据实际业务调整。
知识体系总览
下面这张图,我把这三个技术的关系和核心要点画出来了。你可以看到,它们虽然独立,但都围绕着同一个目标:让Android的网络通信更安全。
这三个技术,说白了就是给Android的网络通信上了三道保险。TLS 1.3管传输过程,CT管证书可信度,HTTP/2管协议层面的安全。我在实际项目中,一般会把这三点都考虑进去,而不是只做其中一两个。
嗯,今天就聊到这儿。这些内容看起来多,但真正用起来,你会发现它们其实是一套组合拳。下次你在做安全审计的时候,不妨对照着这张图,看看自己的App还缺哪一块。