2. 密码学基础回顾:对称加密、非对称加密、哈希函数、数字签名

讲TLS 1.3之前,我觉得有必要先把密码学的那几个老底子翻出来晒一晒。你想想看,TLS本质上就是把这些密码学组件组合起来,形成一套安全的通信协议。说白了,如果你不懂对称加密和非对称加密的区别,那后面理解握手过程一定会一头雾水。

我在早年做嵌入式安全的时候,曾因为混淆了哈希和加密的概念,导致一个固件签名校验的逻辑存在致命漏洞。从那以后,我每接触一个协议,都会先把底层的密码学原语捋清楚。嗯,这也是我把这一章放在最开始的原因。

核心观点: TLS 1.3 的安全性,完全建立在这四个密码学原语的正确组合之上。任何一环节出问题,整个协议都不可信。

2.1 对称加密:安全通道的“主力干将”

对称加密,说白了就是加密和解密用同一把钥匙。你在群里发一个加密文件,大家用同一个密码打开,这就是对称加密的思路。

在TLS里,对称加密负责真正的数据传输加密。握手阶段结束后,双方协商出一个对称密钥,之后所有的HTTP请求、响应都靠它加密。为什么不用非对称加密直接加密数据?非对称加密太慢了,做少量握手还行,用来加密大流量内容,性能上扛不住。

对称加密的两个关键指标:

  • 密钥长度:一般是128位、256位。我个人建议,现在至少用128位,最好用256位。别问我为什么——我在一个遗留系统上见过64位密钥的DES,结果审计直接亮红灯。
  • 加密模式:早期用CBC,现在主流是GCM。GCM自带认证,能防篡改。我曾经踩过一个坑,只用AES-CBC没配合MAC,结果被填充预言攻击搞得很惨。
个人经验: 在TLS 1.3里,对称部分只选AEAD(如AES-128-GCM、ChaCha20-Poly1305)。这相当于把加密和认证合并了,省去了单独配置MAC的麻烦,也减少了我当年那种“忘了加MAC”的低级错误。

2.2 非对称加密:握手阶段的“灵魂角色”

非对称加密,有一对密钥:公钥公开,私钥保密。你用公钥加密,只有私钥能解开;用私钥签名,公钥能验证。这一特性完美解决了对称加密中密钥分发的问题——双方不需要事先共享一个秘密,就能通过非对称密码建立起信任。

在TLS 1.3里,非对称加密主要用于两件事:

  1. 密钥协商:通过ECDHE(椭圆曲线Diffie-Hellman)交换临时密钥材料,计算出共享对称密钥。
  2. 身份认证:通过私钥签名证书,证明服务器(或客户端)的身份是真的。

常见的非对称算法有RSA、ECDSA、Ed25519。RSA曾经是主流,但现在我建议新系统直接上ECDSA或Ed25519。为什么?RSA密钥太长、计算慢,而且RSA-1024已经被攻破,RSA-2048虽然还没事,但能上椭圆曲线就上椭圆曲线,性能好一大截。我记得有一次进行大规模HTTPS压测,用RSA握手时CPU直接跑满,换成ECDHE瞬间降下来了。

特性 RSA ECDSA(P-256) Ed25519
密钥长度(安全强度) 2048位~128位强度 256位~128位强度 256位~128位强度
签名速度 较慢 快 极快
握手性能 CPU消耗高 轻量 最轻
TLS 1.3支持 有限制 完美支持 完美支持
避坑指南: 我曾经帮一个客户排查TLS握手失败的问题,发现他用的RSA证书只有1024位,而客户端已经默认拒绝任何低于2048位的证书。所以别心存侥幸,部署前检查一下你的证书密钥强度。

2.3 哈希函数:数据完整性的“守门员”

哈希函数,就是把任意长度的数据,映射成一个固定长度的摘要。这个过程是单向的——你从摘要几乎不可能反推出原数据。哈希函数天生适合做完整性校验:发文件之前算个哈希,收文件之后重新算一遍,一致就说明文件没被改过。

在TLS 1.3里,哈希函数无处不在:

  • 握手消息的哈希链:每一步握手,都会把当前消息的哈希值存下来,用于验证整个握手的一致性。
  • 密钥派生:使用HKDF(基于HMAC的密钥派生函数),从初始密钥材料派生出真正的对称密钥。
  • 签名摘要:在数字签名中,先对消息做哈希,再对哈希值签名,提高性能并防止消息过长。

常见的哈希算法有SHA-256、SHA-384、SHA-512。SHA-1已经被废弃,因为碰撞攻击已经在现实中实现了。我记得有一次听说某个大厂内部还在用SHA-1签名固件更新,这简直是给攻击者开绿灯。TLS 1.3直接规定必须用SHA-256及以上,我举双手赞同。

一句话总结: 哈希不提供机密性,只提供完整性。加密数据保证了你看不懂,哈希保证了你看的内容确实是我想给你的。

2.4 数字签名:身份认证的“铁证”

数字签名,就是非对称加密的逆用。私钥持有者对消息哈希值签名,公钥持有者验证签名是否匹配。这解决了两个关键问题:

  • 身份可信吗? 只要公钥属于某人,且签名能通过验证,消息一定是他签的。
  • 消息被改过吗? 签名带上了哈希,任何改动都会让验证失败。

在TLS 1.3里,数字签名是“证书验证”的核心。服务器发来证书后,客户端用CA的公钥验证服务器证书上的签名,如果通过,就证明服务器持有对应私钥。之所以需要这个环节,是因为非对称密钥交换本身不能防止中间人攻击——你需要数字签名加上证书链,才能确定你手里的公钥真的是对方的。

TLS 1.3改变了签名策略:不再允许RSA签名中的PKCS#1 v1.5填充,改用RSA-PSS。我当年学习TLS 1.2时,对PKCS#1 v1.5填充的攻击历史印象深刻——针对它的攻击(如Bleichenbacher攻击)曾经非常猖獗。TLS 1.3直接禁用了它,算是彻底把这个隐患斩断了。

经验之谈: 在调试TLS 1.3握手时,如果遇到证书验证失败,优先检查:
1. 签名算法是否被服务器和客户端共同支持(看Supported Signature Algorithms扩展)。
2. 证书是否过期或吊销。
3. 是不是用了RSA-PSS——有些旧CA还不知道这个算法,容易出兼容性问题。
TLS 1.3 密码学基础架构图 TLS 1.3 密码学基础架构图 对称加密 AES-GCM / ChaCha20-Poly1305 非对称加密 ECDHE / RSA / ECDSA 哈希函数 SHA-256 / SHA-384 数字签名 RSA-PSS / ECDSA / Ed25519 核心关系 非对称加密(ECDHE)协商对称密钥 → 对称加密(AEAD)加密数据 → 哈希函数保障完整性 → 数字签名验证身份 数据加密与传输

上面这张图就是我对TLS 1.3密码学基础的总结。你想想看,非对称加密负责握手阶段的密钥协商和身份认证,对称加密负责后续数据的大规模加密,哈希函数为握手提供完整性保障并为签名提供摘要,数字签名则为整个信任链背书。这四个原语互相配合,缺一不可。

本章小结: 对称加密管数据机密性,非对称加密管密钥交换和身份证明,哈希函数管数据完整性,数字签名管身份认证和防抵赖。在TLS 1.3中,它们不是孤立存在的——而是像齿轮一样紧密咬合,共同构成安全通道。