密码学基础:四把钥匙开一把锁

做 TLS 配置这么多年,我最深的体会是:密码学不是数学课,而是信任链。对称加密、非对称加密、哈希函数、数字签名——这四样东西你搞明白了,TLS 的握手过程基本就通了一半。

先看一张整体图,后面我再逐个掰开讲。

密码学基础四件套 对称加密 相同密钥加密/解密 非对称加密 公钥/私钥对 哈希函数 单向摘要 速度慢 互补 数字签名 = 哈希 + 非对称加密 保证完整性 + 身份认证 + 不可否认 依赖 依赖 💡 TLS 握手中:先用非对称交换对称密钥,再用对称密钥加密通信内容,同时用哈希+签名验证证书

对称加密:又快又简单,但密钥怎么传?

对称加密,说白了就是一把钥匙开一把锁。发信人和收信人用同一个密钥加密、解密。典型的算法有 AES、ChaCha20。

我刚开始做网站安全的时候,觉得对称加密好理解,直接 AES-256-GCM 一把梭。但后来在生产环境出了个事故——用的密钥是写死在配置文件里的,结果服务器被拖库,所有加密流量都能解。嗯,这里要注意:对称加密的核心问题不是算法不够强,而是密钥分发。

  • 优点:速度快,适合大量数据加密(比如 TLS 记录层)。
  • 缺点:密钥必须通过安全通道传递。如果密钥被截获,加密形同虚设。
  • TLS 中的角色:握手完成后,用协商出的对称密钥加密实际 HTTP 请求。
我的习惯:生产环境从不硬编码密钥。用密钥管理服务(KMS)或 HashiCorp Vault 自动轮换。曾经有个项目没轮换密钥,用了两年……想想都后怕。

非对称加密:公钥随便给,私钥藏好

非对称加密解决的就是密钥分发难题。每个人生成一对密钥:公钥公开,私钥自己保存。数据用公钥加密后,只有对应的私钥能解开。主流算法有 RSA、ECDSA、Ed25519。

你可能在想:那为什么不全用非对称?因为慢啊。RSA 加密几百字节就要几毫秒,而 AES 加密 1MB 数据也就几十微秒。实际做法是:用非对称加密传输一个临时对称密钥,后续通信全部走对称加密。这就是 TLS 握手的核心思路。

特性对称加密非对称加密
密钥数量1 个2 个(公钥+私钥)
速度极快慢(RSA 比 AES 慢 1000 倍以上)
典型算法AES-256-GCMRSA-4096, ECDSA P-256
TLS 用途记录层加密密钥交换、数字签名
曾经有个客户为了图省事,直接拿私钥当公钥用……结果所有人都能解密。记住:私钥不可泄露,公钥随便发。

哈希函数:单向的“指纹”

哈希函数能把任意长度的输入,变成固定长度的输出(比如 SHA-256 输出 256 位)。而且这个过程不可逆——你无法从摘要恢复原始数据。常见的哈希算法有 SHA-256、SHA-3。

为什么 TLS 需要哈希?你想,如果通信内容被篡改,接收方能不能察觉?哈希提供完整性校验。接收方收到数据后,重新算一遍哈希,和发送方提供的哈希对比——不同就说明被篡改了。

避坑:我曾经见过有人把 MD5 用在 TLS 里验证证书。MD5 早被破解了,碰撞攻击能伪造相同哈希的不同内容。现在 SHA-1 也已被弃用,至少用 SHA-256。

数字签名:谁发的?验一下

数字签名 = 哈希 + 非对称加密。签名者先对消息做哈希,然后用自己私钥加密这个哈希值,得到签名。验证者用签名者的公钥解密签名,拿到哈希值,再和自己算的哈希对比。如果一致,说明消息确实来自签名者,且未被篡改。

我在项目中遇到过最坑的事:某个 CA 签名时用的哈希算法是 SHA-1,浏览器都报安全警告。换信任链花了两周……

  • 作用:身份认证(确认对方是证书持有者) + 完整性(内容没被改) + 不可否认(签名者无法抵赖)。
  • TLS 中的应用:服务器发送证书,证书里有 CA 的数字签名;客户端验证签名,确认服务器身份。

四者如何协作?

拿一次简单的 TLS 握手举例(别慌,后面章节会细讲):

  1. 客户端连接服务器,服务器发来证书(包含公钥)。
  2. 客户端用 CA 的公钥验证证书上的数字签名(哈希+非对称)。
  3. 客户端随机生成一个对称密钥,用服务器公钥加密后发过去(非对称加密)。
  4. 服务器用私钥解密,得到对称密钥。
  5. 后续所有 HTTP 数据都用这个对称密钥加密(对称加密),并且每条消息带上哈希校验。
你想想看:如果没有哈希,攻击者截获加密数据后虽然解不开,但可以随机篡改比特位,接收方无法检测。哈希保证了每一字节的完整性。