第2章 密码学基础速览:对称加密、非对称加密、哈希函数、数字签名与MAC

说实话,很多搞网络协议的朋友,一上来就啃TLS握手细节,结果被密钥交换、证书链这些东西搞得一头雾水。归根结底,是密码学底子不够扎实。我不是说要你去啃数论或椭圆曲线,但核心的几个密码学原语——对称加密、非对称加密、哈希、数字签名、消息认证码——必须得搞明白它们各自解决什么问题、有什么坑。

我个人习惯,把TLS握手的本质看成一个「三步走」:身份验证、密钥协商、安全传输。每一步都依赖不同的密码学工具。本章我们就先把这些工具过一遍,后面讲到握手流程时,你自然就知道它们用在哪了。

核心观点:TLS 的安全性不是靠某一种算法,而是靠对称加密、非对称加密、哈希、签名、MAC 这五类原语的组合拳。缺一个,或者用错一个,整个安全体系都可能崩塌。

2.1 对称加密:速度快,但密钥怎么给?

对称加密,说白了就是加密和解密用同一把钥匙。你拿钥匙锁门,别人拿同一把钥匙开门。这个“钥匙”在密码学里叫密钥(Secret Key)。

常见的对称加密算法有:

  • AES(高级加密标准):当今最主流的分组密码,密钥长度128/192/256位。TLS 1.2/1.3都在用。
  • ChaCha20:流密码,在移动设备上性能特别好,Google 和 Cloudflare 都在推。
  • DES/3DES:老古董了,现在已被禁用。我几年前做项目迁移时,还在遗留系统里见过3DES,赶紧建议对方换掉了。

对称加密最大的优势是快。硬件加速后,AES加解密能做到几GB/s。但它有个致命问题——密钥分发。假如你和我通信,咱们得事先共享同一个密钥。那这个密钥怎么安全地传给对方?通过电话?快递U盘?都不现实。

我在项目中遇到过团队直接用对称加密做API鉴权,结果密钥硬编码在App里,反编译一下就全泄露了。嗯,这其实不是算法的问题,是没搞懂「密钥如何安全协商」。

小提示:TLS 握手的第一步,就是靠非对称加密来解决对称密钥的分发问题。所以对称加密和非对称加密在TLS里是搭档,不是对手。

2.2 非对称加密:公钥加密,私钥解密

非对称加密的概念改变了很多人的认知。它使用一对密钥:一个叫公钥,可以公开给全世界;另一个叫私钥,必须自己藏好,谁也不能给。

它有两个核心用法:

  1. 加密:别人用你的公钥加密数据,只有你能用私钥解密——这解决了对称加密的密钥分发问题。
  2. 签名:你用私钥签名一段数据,别人用你的公钥验证签名是否有效——这解决了身份认证问题。

常见的非对称算法:

  • RSA:最经典,支持加密和签名。位数越长越安全,现在推荐至少2048位。但RSA签名速度慢,且密钥对生成很耗时。
  • ECC(椭圆曲线密码学):同样安全强度下,密钥长度比RSA短得多。比如256位ECC ≈ 3072位RSA。TLS 1.3基本都在推ECC。
  • DH/DHE:严格来说它不是加密算法,而是密钥交换协议。后面章节我们会详细讲。
特性 对称加密 非对称加密
密钥数量 1个(共享密钥) 2个(公钥+私钥)
速度 极快(硬件加速可达GB/s) 慢(比对称加密慢100-1000倍)
密钥分发 困难,需安全通道 公钥可公开,私钥本地保存
典型用途 大量数据加密 密钥交换、数字签名

举个例子:我在配置TLS时,证书里的公钥就是非对称的。握手时,客户端用这个公钥加密一个随机数发给服务器,服务器用私钥解密,从而安全地建立共享密钥。你想想看,如果没有非对称加密,这个随机数在网络上裸奔,整个会话瞬间就废了。

⚠ 注意:非对称加密不是万能的。我曾经见过有人用RSA公钥直接加密大文件,结果性能惨烈,几秒钟都没反应。记住,实际应用中是「非对称加密密钥、对称加密数据」。

2.3 哈希函数:数据指纹的“摘要器”

哈希函数(Hash Function)是一个非常有意思的工具。它能把任意长度的输入,变成固定长度的输出(比如256位)。这个输出叫哈希值或摘要。而且,它有几个重要特性:

  • 单向性:从哈希值无法反推出原始数据。
  • 抗碰撞性:很难找到两个不同的输入产生同样的哈希值。
  • 雪崩效应:输入哪怕改一个比特,哈希值几乎会完全变化。

常见的哈希算法:SHA-2(SHA-256/384/512)是TLS的主流选择。SHA-1已经不安全了,2017年后主流浏览器基本都拒绝SHA-1证书。我经历过一次因为使用SHA-1证书导致的浏览器兼容性事故,那时候真是手忙脚乱。

哈希在TLS里至少有四个重要用途:

  1. 证书指纹:验证证书是否被篡改。
  2. 消息完整性:配合MAC使用,确保数据在传输中没被修改。
  3. 密钥派生:通过PRF(伪随机函数)混合输入,生成会话密钥。
  4. 数字签名的基础:先对数据进行哈希,再对哈希值签名,而不是直接签名原始数据。
实用技巧:你在浏览器里看HTTPS证书详情时,看到的「SHA-256指纹」就是对整个证书内容做哈希的结果。你可以自己算一个证书的SHA-256,对比一下是不是一样。

2.4 数字签名:让公钥变成“可信的”

光有非对称加密还不行。你想,中间人也可以生成一对密钥,把公钥发给你,然后你用它加密的数据全被中间人解密了。你怎么知道这个公钥真的是服务器的?数字签名(Digital Signature)就是解决这个问题的。

数字签名的流程很清晰:

  1. 发送方对数据(或其哈希值)用私钥进行签名运算,生成签名值。
  2. 接收方用发送方的公钥验证签名是否有效。
  3. 如果验证通过,说明数据确实来自私钥持有者,且未被篡改。

我在一次安全审计时发现,某个系统为了让伪造的请求通过验证,直接硬编码了服务器的公钥。这其实就绕过了签名的意义——公钥必须是可信的、经过证书链验证的。TLS里通过数字证书来绑定公钥和身份(比如域名)。证书是由CA(证书颁发机构)签名的。你浏览器里预置了根证书,顺着证书链一层层验证,最终确认服务器的公钥是真的。

常见的签名算法:RSA签名和ECDSA(椭圆曲线数字签名算法)。ECDSA签名更短,性能更好,在移动端和物联网场景优势明显。

2.5 MAC与HMAC:防篡改的“封装锁”

最后一个原语是消息认证码(MAC)。它和哈希有点像,但多了一个共享密钥的输入。

MAC的核心能力:

  • 发送方用共享密钥对消息计算MAC值,随消息一起发送。
  • 接收方用同样的密钥和收到的消息重新计算MAC,比对是否一致。
  • 如果一致,说明消息未被篡改,且确实来自持有共享密钥的一方。

MAC和哈希的区别:哈希只有输入数据一个参数;MAC有两个参数(数据和密钥)。简单来说,MAC保证了在不知道密钥的情况下,攻击者无法伪造合法消息。TLS里最常用的MAC是HMAC(基于哈希的MAC)。比如HMAC-SHA256就是先用SHA-256加密钥处理消息。

2.6 它们是如何协同工作的?

我们把上面几个概念串起来,看看在TLS握手里它们实际怎么配合:

  1. 身份认证:服务器发送证书(含公钥),CA用数字签名保证证书可信。客户端验证签名通过。
  2. 密钥协商:客户端用服务器公钥加密一个随机数,或使用DH/ECDH密钥交换,双方各自计算出相同的预主密钥(Pre-Master Secret)。然后用PRF派生出一堆会话密钥(包括对称加密密钥和HMAC密钥)。
  3. 安全传输:之后的数据用对称加密(如AES)加密,同时附加HMAC保证完整性。接收方解密并验证HMAC,确保数据在传输中没被篡改。

你看,每个密码学工具各司其职。非对称加密和签名搞定握手阶段,对称加密和HMAC搞定数据传输阶段,哈希函数则是众多安全机制的基础砖石。

下面这张图梳理了本章的核心知识体系:

密码学基础:TLS 安全原语 对称加密 AES / ChaCha20 非对称加密 RSA / ECDH 哈希函数 SHA-256 / SHA-3 数字签名 RSA签名 / ECDSA MAC / HMAC HMAC-SHA256 TLS 安全组合拳 阶段一:身份认证 数字签名 + 证书链 哈希用于证书指纹 阶段二:密钥协商 非对称加密 / DH密钥交换 哈希用于密钥派生(PRF) 阶段三:安全传输 对称加密(AES/ChaCha20) MAC(HMAC)防篡改 关键:非对称加密 + 数字签名构建信任基座,对称加密 + MAC 保证传输效率和安全

这张图把五个原语和TLS三个阶段的关系画得很清楚。你可以看到,哈希函数横跨三个阶段,它在证书指纹、密钥派生、PRF里都有出现。

2.7 避坑小集

最后,我整理几个自己踩过的坑,以及经常被问到的误区:

  • 千万别用SHA-1:我曾经维护一个老旧系统,发现证书还是SHA-1,结果被安全扫描工具报高风险,赶紧走流程更换。现在主流浏览器都禁了SHA-1证书。
  • 对称加密要注意模式:比如AES-ECB模式不安全,同样的明文块会得到同样的密文块。TLS里用的是GCM或CBC(配合HMAC)。分不清模式的人写代码会出大问题。
  • 密钥不能硬编码:我见过太多项目把对称密钥或私钥写在配置文件里提交到Git仓库。一旦泄露,整个系统就废了。正确的做法是用密钥管理服务(KMS)或硬件安全模块(HSM)。
  • 不要自己拼算法:你用AES加密数据,自己设计一个MAC方案?别闹了。TLS有标准化的记录层协议,所有细节都定好了。用开源库才是正解。