SSL/TLS:关键概念与协议在编程中的应用

作者: IT Sectr 发布日期: 2026-03-09 阅读时间: 9 分钟

SSL/TLS — 加密移动应用与服务器之间数据的密码协议,保证流量的机密性和完整性。根据Apple(2026年)的数据,App Transport Security默认在所有iOS设备上阻止TLS 1.2以下的连接。TLS 1.3与TLS 1.2相比,将握手时间缩短了2倍,改善了移动应用的UX。

要点

  • TLS — 现代密码协议,是已过时SSL的继任者,具有更强的保护能力。
  • TLS 1.3以1 RTT完成握手(TLS 1.2需要2 RTT),加速加载。
  • App Transport Security — Apple的机制,要求在iOS上使用TLS 1.2+的HTTPS。
  • Network Security Config — 通过XML为Android配置HTTPS。
  • Certificate Pinning — 通过固定代码中的证书指纹来抵御MitM攻击。

什么是SSL/TLS?

SSL(安全套接层)和TLS(传输层安全)—— 确保通过网络安全传输数据的密码协议。SSL由Netscape在1990年代开发,由于POODLE和BEAST漏洞,在3.0版本后被宣布过时。TLS作为其继任者,经历了1.0、1.1、1.2和1.3版本——目前只有TLS 1.2和TLS 1.3被认为是现代的。所有现代移动平台都要求网络连接使用TLS,App Store和Google Play在审核阶段会对此进行检查。

为什么移动应用需要TLS

没有TLS,应用和服务器之间的流量以明文形式传输——同一Wi-Fi网络中的任何人都可以使用Wireshark或tcpdump截获用户名、密码、令牌和用户的个人数据。TLS加密所有传输的数据(传输层加密),并通过X.509证书链验证服务器的真实性。根据IETF(2018年),TLS 1.3仅使用现代AEAD加密算法(AES-GCM、ChaCha20-Poly1305),排除了RC4和3DES等过时算法。

HTTPS与TLS

HTTPS(HTTP安全)—— 是基于TLS的HTTP。当移动应用通过https://发出请求时,它首先与服务器建立TLS连接,然后通过加密通道传输HTTP标头和请求体。没有HTTPS,任何严肃的API都不应该工作——这是基本的安全卫生。根据OWASP(2026年),不安全连接位列移动应用三大漏洞之一。

TLS握手如何工作

TLS握手 — 在客户端和服务器之间建立安全连接的过程。双方协商协议版本,选择密码套件,通过非对称密码学交换密钥,并验证证书。在TLS 1.2中,握手需要2次往返时间(2 RTT):客户端→服务器发送ClientHello,服务器→客户端发送ServerHello和Certificate,然后发送Finished消息。TLS 1.3将此过程缩短为1 RTT。

TLS 1.2握手的详细阶段

第一阶段:ClientHello — 客户端发送支持的TLS版本、密码套件列表和随机数。服务器用ServerHello响应,选择版本和密码套件,发送其X.509证书(Certificate)和ServerHelloDone消息。客户端通过受信任的证书颁发机构(CA)链验证证书,生成预主密钥,用证书中的公钥加密并发送到ClientKeyExchange中的服务器。之后,双方生成会话密钥并交换ChangeCipherSpec和Finished消息。从此刻起,所有数据都进行对称加密。

swift
import Security

let url = URL(string: "https://api.example.com")!
let session = URLSession(configuration: .default,
                           delegate: self,
                           delegateQueue: nil)

func urlSession(
    _ session: URLSession,
    didReceive challenge: URLAuthenticationChallenge,
    completionHandler: @escaping (URLSession.AuthChallengeDisposition,
                                    URLCredential?) -> Void
) {
    let trust = challenge.protectionSpace.serverTrust
    guard let trust else {
        completionHandler(.cancelAuthenticationChallenge, nil)
        return
    }
    completionHandler(.useCredential, URLCredential(trust: trust))
}

通过URLSessionDelegate在iOS上处理URLAuthenticationChallenge的示例。每次TLS握手时都会调用此方法,允许应用自定义验证服务器证书。对于生产环境,通过SecTrustEvaluateWithError添加证书验证并与预先保存的指纹进行比较——然后才调用useCredential。

TLS 1.2与TLS 1.3对比

TLS 1.3(RFC 8446,2018年)—— 该协议10年来的首次重大更新。主要改进:握手减少到1 RTT(重新连接时为0 RTT),删除了过时的密码套件(RSA密钥交换、CBC模式),强制前向保密(PFS)以及通过签名记录防止降级攻击。根据Qualys SSL Labs(2026年)的数据,TLS 1.3凭借PFS即使在长期服务器密钥被泄露时也能提供保护。

特性TLS 1.2TLS 1.3
握手2 RTT(完整)1 RTT(PSK时为0 RTT)
密码套件30+种组合(RSA、DH、ECDH)5种AEAD套件(AES-GCM、ChaCha20)
前向保密可选(DHE、ECDHE)强制(所有套件)
iOS支持iOS 5+iOS 12+
Android支持Android 4.0+Android 10+
过时算法RSA、CBC、RC4、3DES已完全移除

0-RTT(零往返时间) — TLS 1.3的功能,允许客户端在通过PSK(预共享密钥)重新连接时立即与ClientHello一起发送数据。这加速了移动应用中后续屏幕的加载,特别是当频繁向同一服务器发送请求时。但是,0-RTT数据无法抵御重放攻击——可以被拦截并重新发送。仅对无副作用的幂等请求(GET、PUT)使用0-RTT。

iOS上的TLS:App Transport Security

App Transport Security(ATS) — Apple的机制,要求使用TLS 1.2或更高版本的HTTPS连接,自iOS 9起默认启用。ATS阻止所有HTTP连接和TLS低于1.2的HTTPS。开发者可以通过Info.plist中的NSAppTransportSecurity为特定域配置例外,但Apple建议尽量减少例外并尽量使用HTTPS。违反ATS要求是在App Store审核时拒绝应用的原因。

xml
<!-- Info.plist — App Transport Security -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>cdn.example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
        </dict>
    </dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

Info.plist中的ATS配置。NSAllowsArbitraryLoads设置为false——所有连接必须使用HTTPS。对于域名cdn.example.com,设置了最低TLS 1.2版本,NSAllowsLocalNetworking=true允许本地网络的HTTP(对开发服务器有用)。Apple强烈建议不要在没有NSExceptionDomains的情况下启用NSAllowsArbitraryLoads——这应该是例外,而不是通用规则。

Android上的TLS:Network Security Config

Network Security Config — Android用于配置HTTPS和TLS而无需修改Java/Kotlin代码的机制。配置在XML文件network_security_config.xml中定义,并通过android:networkSecurityConfig属性在AndroidManifest中连接。支持配置受信任的证书(用户和系统CA)、Certificate Pinning、禁用明文HTTP、调试覆盖和流量重定向。

xml
<!-- res/xml/network_security_config.xml -->
<network-security-config>
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">api.example.com</domain>
        <pin-set expiration="2027-01-01">
            <pin digest="SHA-256">
                47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
            </pin>
        </pin-set>
    </domain-config>
</network-security-config>

Android的Network Security Config。Base-config禁止明文流量,仅信任系统CA证书(不信任用户证书——防止用户安装MitM证书)。api.example.com的Domain-config包含带有证书SHA-256指纹的pin-set。如果服务器证书在指定的到期日期之前更改,连接将被拒绝——这是Certificate Pinning的严格形式。

Certificate Pinning与安全性

Certificate Pinning — 在应用代码中固定服务器证书或公钥的技术。每次TLS握手时,客户端将服务器证书与预先保存的指纹(SHA-256哈希)进行比较。即使攻击者获得了可信的CA证书或入侵了证书颁发机构,也无法执行MitM攻击——应用检查的是特定指纹,而不是CA链。这对于金融应用和包含敏感数据的应用尤其重要。

Pinning的风险和替代方案

Certificate Pinning需要谨慎:当服务器上的证书更改时,所有旧版本的应用将无法连接。建议保存多个备用指纹(主用+备用),指定pin-set的到期日期,并通过标准CA验证实现回退机制。替代方案是首次使用时信任(TOFU),即应用在第一次连接时记住证书,并在证书更改时警告用户。根据OWASP(2026年),缺少Certificate Pinning位列移动应用三大漏洞之一(M3:不安全通信)。

在Alamofire中实现Pinning

在Alamofire 5+中,Certificate Pinning通过ServerTrustManager配合PinnedCertificatesTrustEvaluator(检查整个证书)或PublicKeysTrustEvaluator(仅检查公钥)进行配置。公钥更优——在相同CA更新证书时不会更改。使用[host: evaluator]字典创建ServerTrustManager,将其传递给Session并用于所有对受保护API的请求。

常见问题

SSL和TLS有什么区别?

SSL — 过时协议(2.0和3.0版本),因POODLE和BEAST漏洞而被认定为不安全。TLS — 其继任者,从TLS 1.0开始(RFC 2246,1999年)。任何现代的“SSL证书”都是TLS协议使用的X.509证书。SSL 3.0在所有现代操作系统和浏览器中已被禁止。

为什么Apple阻止HTTP连接?

App Transport Security — Apple对应用安全性的要求。HTTP以明文形式传输数据,允许在公共Wi-Fi网络中截取令牌和用户的个人数据。ATS默认阻止HTTP和TLS低于1.2的HTTPS,即使没有开发者的操作也能保护用户。

如何检查服务器是否支持TLS 1.3?

使用SSL Labs(ssllabs.com/ssltest)或命令行:openssl s_client -tls1_3 -connect example.com:443。在大多数云平台(AWS CloudFront、Cloudflare、Nginx 1.19+、Caddy)上,TLS 1.3默认启用。在Android 10+上,支持已内置于系统提供商Conscrypt中。

什么是自签名证书,可以在生产环境中使用吗?

Self-Signed Certificate — 由自己而非证书颁发机构签署的证书。不能在生产环境中使用——移动操作系统不信任此类证书。用于本地开发:通过MDM将证书添加到受信任列表中,或使用禁用验证的debug构建。

如何在Alamofire中配置Pinning?

创建ServerTrustManager配合PinnedCertificatesTrustEvaluatorPublicKeysTrustEvaluator。前者检查整个证书,后者仅检查公钥(更优)。将管理器传递给Session(configuration: serverTrustManager:),并对所有向API发出的请求使用该会话。

总结

  • TLS — 现代加密协议,过时SSL的继任者,所有移动应用必须使用。
  • TLS 1.3以1 RTT完成握手(比TLS 1.2快2倍),强制前向保密且仅使用AEAD加密算法。
  • App Transport Security(iOS)自动阻止所有iOS 9+ Apple设备上的HTTP和TLS低于1.2的连接。
  • Network Security Config(Android)通过XML配置HTTPS、Certificate Pinning和明文限制,无需修改代码。
  • Certificate Pinning — 通过在Network Security Config或ServerTrustManager中固定证书的SHA-256指纹来抵御MitM攻击。
  • TLS 1.3使用5种AEAD密码套件,排除了过时的RSA密钥交换和CBC模式。
  • TLS配置是强制性的发布阶段:App Store检查ATS,Google Play通过Network Security Config检查明文流量。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读