04.07 TLS 与身份:加密一条连接不等于授权一条消息
返回第四卷 · 地址与名称:04.02 · 长连接:04.05 · 认证授权:09.07
04.07 TLS 与身份:加密一条连接不等于授权一条消息
DeepTutor 初稿经技术与教学审阅后的静态课程。域名、证书、握手与故障均为虚构纸上示例;本次没有运行 Go、TLS 握手、IM 服务或站点,也不声称核对了 OpenIM 的部署证书或加密配置。
一、A 看到 HTTPS 小锁,还要问哪一跳被保护
虚构 u-a 的浏览器访问 https://im.example.test,再以 wss://im.example.test 连到教学 IM 网关,发送 m-a。04.04–04.06 已讲 TCP 怎样确认字节、连接怎样重连、慢设备与网络怎样拖慢它。现在网络路径上可能有旁观者读取或篡改字节,或者把 A 引向冒名服务。TLS 在正确配置和验证下,给这段通信提供机密性、完整性与对服务端身份的校验;它并不替应用回答 A 是否已登录、有无 c-a 权限、消息是否写入或 B 是否已读。
A 浏览器 ── HTTPS/WSS 的 TLS ── 反向代理/网关 ── 另一条待定义连接 ── Go 服务
保护这一跳的传输 解密处是新的信任边界如果 TLS 在反向代理终止,代理后面走明文还是另一条 TLS,需要单独核对。浏览器的小锁图标只反映它眼前的连接检查,不能推断数据库、队列和 B 设备之间也全程加密。这里仍只用虚构 u-a/u-b/c-a/m-a,没有真实证书或流量记录。
| 第一遍 | 第二遍 | 交付物 |
|---|---|---|
| 加密/签名、证书、握手、名称校验 | 代理两跳、Go 配置、mTLS、0-RTT 重放 | HTTPS/WSS 分层图、证书判断表、失败边界表 |
二、四个基础词:对称密钥、哈希、公私钥与签名
对称加密让通信双方持有相应的共享秘密,用它高效保护大量应用数据。现代 TLS 记录层采用认证加密(AEAD)一类机制,让密文在正确密钥下既能保密,也能检测不被允许的修改。哈希把输入映射为摘要,可参与握手/完整性计算,但“给消息算一个公开哈希”本身不阻止攻击者改消息并重算摘要。公私钥成对使用:私钥应只由持有者控制,公钥可供他人验证相应的签名。数字签名用于证明某份被签内容与持有私钥的一方关联,它不等于把聊天正文加密。
在 TLS 1.3 的常见完整握手中,双方交换临时密钥协商材料,导出本次连接所需的对称密钥;服务器用证书及对握手的签名证明自己掌握与证书公钥对应的私钥。不要把它讲成“浏览器拿服务器证书公钥直接加密每条 m-a,服务器拿长期私钥逐条解密”。那会误导读者对会话密钥、前向保密与证书职责的理解。
| 物件 | 在本章做什么 | 不能单独做什么 |
|---|---|---|
| 对称会话密钥 | 保护这次连接上的应用数据 | 证明远端到底是哪个服务,除非握手已认证 |
| 哈希摘要 | 为协议完整性和密钥推导提供材料 | 独自认证“消息来自可信网关” |
| 证书中的公钥 | 给身份签名校验提供公钥 | 自动证明 URL 名称匹配或 A 是合法成员 |
| 私钥签名 | 证明持钥者参与已签握手 | 保证 B 已收到、服务器入库成功 |
应用开发者通常应使用维护中的 TLS 库与默认验证流程,不自己拼加密协议。本章只建立可审阅的因果关系,具体算法组合由所用 TLS 版本和实现协商。
三、把 TLS 1.3 握手放在 TCP 与 HTTP 之间
在本章的 HTTPS/WSS 路径里,先有 TCP 连接,再协商 TLS,之后才在受保护的通道上运行 HTTP 请求或 WebSocket 升级。TLS 1.3 的一轮简化教学时间线如下;真实报文、加密时点和可选路径比这张图更细:
| 次序 | 客户端/服务端主要动作 | 本章学到的边界 |
|---|---|---|
| 1 | 客户端发 ClientHello,提出支持的版本、临时密钥份额,以及可能的 SNI/ALPN | 客户端表明要连接哪个服务和可用协议能力;尚未据此相信对端 |
| 2 | 服务端发 ServerHello 并选择参数/密钥份额 | 双方开始导出握手与后续应用数据所需密钥 |
| 3 | 服务端发证书、CertificateVerify 与 Finished 等消息 | 客户端要核对证书链、目标名称和握手完整性 |
| 4 | 客户端完成自己的握手确认 | 验证成功后才把后续 HTTP/WS 应用数据当作此 TLS 对端的通信 |
对于 https://im.example.test,TLS 上面是 HTTP;对于 wss://im.example.test,TLS 上先承载 HTTP 升级,再是 WebSocket 帧。TCP 三次握手成功不等于 TLS 握手成功;TLS 成功不等于 WebSocket 返回 101,也不等于应用 Session 合法。网络旁观者仍可看到一些连接元数据,例如目的地址、流量时刻与大小;本章不把 TLS 描述成“路径上任何信息都不可见”。
TLS 1.3 之后的数据由本次会话密钥保护,不应把握手证书与每条业务消息做一一映射。一个 TCP/TLS/WS 长连接可以承载多条 m-a/m-b 等应用消息,它们各自还要有消息 ID、权限和业务确认。
四、证书链可信,还必须匹配 im.example.test
A 打开 https://im.example.test,客户端至少要核对:证书能沿受信链验证到可接受的根;证书处于有效时间并适合所需用途;证书的 Subject Alternative Name(SAN) 中有与目标名称匹配的 DNS 名称。DNS 把域名解析为某个 IP,只帮找到网络位置,不等于证明那个 IP 上的服务有权自称 im.example.test。现代名称校验也不能只盯着旧式 Common Name 字段。
| 纸上证书情况 | 应得的判断 |
|---|---|
受信链 + 有效时间 + SAN 包含 im.example.test | 满足此处服务端证书的基础名称条件,仍需完成 TLS 握手 |
受信链但 SAN 只有 other.example.test | 名称不匹配;不能用“证书是真的”跳过 |
| SAN 正确但证书已过期/尚未生效 | 时间条件失败,不能当正常服务身份 |
| 名称正确但签发链不受客户端信任 | 信任链失败,不能凭名称字符串放行 |
SNI 是客户端在握手里告诉多站点服务器“希望连接哪个名称”的信息,便于服务器选择证书;它不是客户端验证结果。Go crypto/tls.Config.ServerName 可参与服务端证书名称校验及握手的虚拟主机选择;crypto/x509.Certificate.VerifyHostname 检查 DNS/IP 名称的匹配规则,但单独名称匹配也不替代证书链验证。如果客户端按 IP 地址访问,需按证书中的 IP SAN 核对,而非假装域名证书一定适用。
Go tls.Config.InsecureSkipVerify=true 会关闭默认的证书链与主机名称校验,可能让中间人冒名成功。不能因为测试环境证书不匹配、系统时钟错或证书到期,就把它当作生产修复。正确方向是定位目标名、受信根、证书链、有效期或测试环境证书;高级自定义验证也必须另行审查,不能用一个布尔值宣称安全。
五、反向代理终止 TLS 后,下一跳重新划边界
教学部署若让浏览器先与边缘代理建立 TLS,代理负责验证/解密并转发给 Go 服务,那么浏览器到代理的机密性在代理处结束。代理到 Go 的内网段若用另一条 TLS,需要自己的证书、名称与信任配置;若明文,须明确该段的可信网络、访问控制和风险。服务端到数据库、消息队列、推送服务也是各自连接,不因入口 HTTPS 自动被保护。
浏览器 ──TLS①──> 代理 ──TLS②或受控明文──> Go 服务 ──另定连接──> 数据库/队列
解密/再转发点代理可能传 X-Forwarded-Proto 等字段让后端知道原始请求是否 HTTPS;这些值只有来自受控代理的转发路径才可作依据,不能无条件信任直接客户端伪造的同名头。否则后端可能误判安全传输、生成错误的重定向或 Cookie 属性。04.09 才系统讲代理和负载均衡,本章先知道“每跳单独判断”。
TLS 也不替应用认证:浏览器在 HTTPS 上仍要交 Session/Token,服务器仍需确认 u-a 可读写 c-a;wss:// 仍须核对浏览器 Origin、长连接上的逐消息权限与注销撤销。对端网关证书正确,也不能证明 m-a 已提交数据库或 B 设备收到。
六、失败诊断与证书轮换:别把握手错误写成业务 404
握手阶段可能因名称不匹配、证书过期、链缺失、根不受信、客户端时钟错误或双方不支持共同的协议参数而失败。客户端通常尚未发出受保护的 HTTP 请求,所以不能把这类错误映射成“IM 会话 c-a 不存在”或“m-a 已拒绝”;应按网络/TLS 阶段记录受控错误类别、目标名称、时间和配置版本,避免日志里泄露私钥、Session Cookie 或消息正文。
证书有有效期,需要续期和轮换。纸上轮换计划至少回答:新证书在旧证书到期前何时可用,SAN 是否覆盖服务域名,代理/Go 服务何时加载,旧连接与新连接分别使用什么状态,以及失败如何回退或停发。已建立的 TLS 连接不会仅因后来证书到期就自动变成一条新的握手;新连接需要按当时证书重新校验,旧连接的应用权限又是另一个状态。不能以“页面仍有小锁”证明新连接一定可建立。
Go 的 crypto/tls 与 crypto/x509 是后续个人实践入口;客户端配置中的目标名称、根证书集合和服务端证书链都要来源明确。测试可以用隔离的测试证书和根,生产私钥不放仓库、不进日志。本章没有运行握手或验证程序,因此只写预期故障分类,不写“证书已有效”。
七、mTLS 与 0-RTT:仍不能跳过 IM 业务身份
一般网站 TLS 首先认证服务器。若另行配置双向 TLS(mTLS),客户端也可出示证书,但那只在既定证书政策下证明某个客户端密钥身份;它不天然等于 IM 用户 u-a,更不等于持证客户端可读所有 c-a 消息。系统仍须决定证书映射到哪个服务/设备,以及用户 Session、成员关系和撤销如何检查。
TLS 1.3 还有可选的 0-RTT 早期数据,其跨连接重放保护弱于普通握手后的数据。若未来某个部署真允许 0-RTT,不能未经应用防重放就把非幂等的 POST m-a 当“绝不会执行两次”;可对这种请求不接受早期数据,或按经过审查的稳定操作身份和重放策略处理。本章没有声称教学服务或 OpenIM 使用 0-RTT。普通 TLS 也不自动实现业务 exactly-once:A 的响应丢失仍需消息 ID、查询与后续重试合同。
加密保护传输途中的字节,不代表端点代码、数据库、日志或设备本地历史都安全。TLS、登录会话、对象授权、数据库确认、设备回执是层层不同的证据。
八、交付两跳图与分层练习
交付:一张 TCP→TLS→HTTP/WS→IM 的握手图,一张四种证书情况的判断表,一张“浏览器→代理→Go→数据源”逐跳加密/解密与认证表,以及“证书失败、登录失败、会话无权、消息结果未知”四类错误的已知/未知/下一证据。所有例子为纸上学习材料,无真实证书与服务。
分层练习:先答,再展开反馈
1. TLS 在本章主要保护什么?
在正确验证下保护相应连接的机密性、完整性和服务端身份。
2. 公开哈希摘要本身能防攻击者改文并重算吗?
不能,单独哈希不提供来源认证。
3. 大量应用数据通常用对称还是每字节非对称加密?
TLS 会话密钥的对称认证加密;证书公钥不是逐条聊天正文的直接加密钥。
4. 数字签名主要证明什么?
被签内容与私钥持有者相关,需结合证书信任与名称校验。
5. TCP 建连成功就证明 TLS 握手成功吗?
不能。TLS 在 TCP 之后另行协商和验证。
6. TLS 成功就证明 WebSocket 已收到 101 吗?
不能。HTTP/WS 升级是更高层步骤。
7. DNS 解析到某 IP 能证明它有权自称 im.example.test 吗?
不能,还须证书链和目标名称等校验。
8. 证书链可信但 SAN 只有 other.example.test,可接受吗?
不应接受为 im.example.test,名称不匹配。
9. 现代名称校验可只看证书 Common Name 吗?
不能。应核对 SAN 中对应的 DNS/IP 名称。
10. SNI 告诉服务器选证书,等于客户端已验证证书吗?
不等于。客户端仍须校验链、名称和有效性。
11. Go `InsecureSkipVerify` 可作为生产证书过期的修复吗?
不应。它跳过默认链和名称校验,会引入冒名风险。
12. 按 IP 访问时,只含 DNS SAN 的证书必然适用吗?
不必然。应按目标 IP 与证书 IP SAN 核对。
13. 代理终止 TLS 后,后端一跳自动受同一 TLS 保护吗?
不会。代理到 Go 服务是另一条需要单独判断的连接。
14. `X-Forwarded-Proto` 来自任意客户端都可信吗?
不能,只能在受控代理转发边界按配置使用。
15. HTTPS 成功能证明 u-a 已登录吗?
不能。应用 Session/Token 仍须验证。
16. WSS 成功能证明 u-a 有权读 c-a 吗?
不能。WebSocket 握手和每条消息仍要做应用授权。
17. 证书名称错误能当作 IM 历史接口 404 吗?
不能。握手可能在 HTTP 请求之前就失败。
18. 已建立 TLS 连接在证书到期一刻就自动完成新握手吗?
不能这样推断;新连接需要按当时证书重新校验。
19. mTLS 客户端证书天然等于用户 u-a 吗?
不等于。证书身份还需映射到服务/设备/用户政策。
20. TLS 1.3 0-RTT 早期数据有普通连接同等的跨连接防重放保证吗?
没有;若启用,要避免未防重放的非幂等发送。
21. TLS 加密能证明 m-a 已写入数据库吗?
不能。数据库提交是独立业务证据。
22. 页面小锁能证明 B 设备已读吗?
不能。那是浏览器到某 TLS 端点的连接状态,不是设备/用户回执。
来源与下一步
- RFC 8446:TLS 1.3:握手、密钥、认证加密及 0-RTT 重放边界。
- RFC 9525:TLS 服务身份:证书中的服务名称与客户端名称校验。
- Go
crypto/tls与crypto/x509:ServerName、根信任和证书名称的 Go API 入口。 - MDN:TLS:浏览器 HTTPS 场景和传输保护边界。
按学习路线,04.04–04.07 的传输、连接、流控和 TLS 前置已成章,下一步进入09.12 完整教学 IM 服务项目课程;具备后续工程前置后回本卷学04.08 Go 网络 I/O。离开本章前,应能分别回答:这条连接加密到哪里、验证了哪个服务名称、应用用户是谁、有权操作哪个会话,以及 m-a 已达到什么业务确认点。