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)开始,系统默认就支持了。你只需要确保你的SSLSocketOkHttp配置正确就行。

// 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 核心特性 • 1-RTT握手(0-RTT可选) • 仅前向安全密钥交换 • 移除不安全套件 • 加密握手消息 Android支持 • Android 10+ 默认支持 • OkHttp 4.x 自动协商 避坑 • 别用COMPATIBLE_TLS • 明确指定TLS版本 Certificate Transparency 核心原理 • 公开日志记录证书 • SCT作为证书“出生证明” • 检测伪造/恶意证书 Android实现 • Android 7.0+ 内置支持 • 默认仅对Google服务启用 • 需自行实现CT验证 注意 • CT ≠ 证书绑定 • 两者互补,建议都用 HTTP/2 安全 安全优势 • 强制TLS加密 • 二进制分帧防篡改 攻击面 • Rapid Reset攻击 • HPACK压缩攻击 • 服务器推送滥用 防范 • 限制并发流数 • 监控流重置频率 • 验证推送来源 三者共同构建Android网络通信的安全基石

这三个技术,说白了就是给Android的网络通信上了三道保险。TLS 1.3管传输过程,CT管证书可信度,HTTP/2管协议层面的安全。我在实际项目中,一般会把这三点都考虑进去,而不是只做其中一两个。

嗯,今天就聊到这儿。这些内容看起来多,但真正用起来,你会发现它们其实是一套组合拳。下次你在做安全审计的时候,不妨对照着这张图,看看自己的App还缺哪一块。

公众号:蓝海资料掘金营,微信deep3321