密码学基础回顾:对称加密、非对称加密、哈希函数

说起来,TLS 的安全根基,就踩在这三大密码学基石上。你别看 TLS 握手流程那么复杂,拆开来看,核心就是这三样东西在相互配合。

我记得刚接触密码学时,总觉得它们各干各的。后来在项目中做协议栈移植,才真正理解它们怎么“打配合”。今天就带你过一遍。

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

对称加密,说白了就是加密和解密用同一把钥匙。你想想看,就像你家大门,进出都用同一把钥匙。

它的优点是快,非常快。硬件加速后,AES 加密吞吐量能到几十 Gbps。所以 TLS 传输数据时,用的是对称加密。

主流算法

算法 密钥长度 模式 我的看法
AES 128 / 256 位 GCM / CBC / CTR 首选,硬件加速广泛
ChaCha20 256 位 流密码 移动端表现优秀,无硬件加速时更稳定
DES / 3DES 56 / 112 位 CBC 已被淘汰,千万别用
警告: 3DES 已经在 TLS 1.3 中被彻底移除。如果你还在维护老系统,请尽快迁移到 AES-GCM。

我的选择:AES-256-GCM

我在项目中踩过一个坑——用了 AES-CBC 模式,但没有加 HMAC。结果被 padding oracle 攻击打得措手不及。后来我学乖了,能用 GCM 就用 GCM。它自带认证,能同时保证机密性和完整性。

// 示例:AES-256-GCM 加密(伪代码)
key = 随机生成 32 字节
nonce = 随机生成 12 字节
ciphertext, tag = AES_GCM_encrypt(key, nonce, plaintext, aad)
// 传输时:nonce + ciphertext + tag
// 解密时:用同样的 nonce 和 key,验证 tag
避坑指南: 我曾经在项目中重复使用了 nonce,结果加密被破解。nonce 必须唯一,推荐用计数器或者随机数。

对称加密的核心问题——密钥怎么安全地给到对方?这就轮到非对称加密出场了。

非对称加密:慢,但能解决密钥分发

非对称加密,一对密钥:公钥加密,私钥解密。你想想看,公钥可以随便给,私钥自己藏好。这样就不用担心密钥传输问题了。

但别高兴太早,非对称加密很慢,比对称加密慢几个数量级。RSA 2048 加密一个 256 位的密钥,大概需要 1-2 毫秒。而 AES 加密几百 KB 数据,也就这个时间。

TLS 中的角色

  • 身份认证: 证书里的公钥验证服务器身份
  • 密钥交换: 保护预主密钥的传输
  • 数字签名: 握手消息的签名验证

我在项目中用过的 RSA 与 ECC

算法 密钥长度 安全强度 性能
RSA 2048 2048 位 112 位 签名慢,验证快
RSA 4096 4096 位 128 位 更慢,用于高安全场景
ECDSA P-256 256 位 128 位 快,密钥小
Ed25519 256 位 128 位 非常快,推荐

我个人习惯推荐 ECDHE + ECDSA 的组合。原因很简单:握手更快,密钥更小。我做过对比测试,ECDHE P-256 比 DHE 2048 快 3-5 倍。

// 示例:ECDHE 密钥交换流程
1. 客户端生成临时密钥对 (client_private, client_public)
2. 服务端生成临时密钥对 (server_private, server_public)
3. 双方交换公钥
4. client 计算:shared_secret = ECDH(client_private, server_public)
5. server 计算:shared_secret = ECDH(server_private, client_public)
// 结果:双方得到相同的 shared_secret
重点: TLS 1.3 中,RSA 密钥交换已经被移除,只保留了 (EC)DHE。原因是 RSA 不能提供前向安全性——私钥泄露,历史会话全废。

哈希函数:指纹,防篡改

哈希函数,输入任意长度的数据,输出固定长度的摘要。你想想看,就像给人拍一张证件照——不管这个人高矮胖瘦,照片尺寸都是固定的。

它的核心特性:

  1. 单向性: 从摘要反推原文,几乎不可能
  2. 抗碰撞性: 找不到两个不同输入有相同摘要
  3. 雪崩效应: 输入改一个比特,摘要完全不一样

哈希在 TLS 中的角色

  • 证书指纹: 验证证书是否被篡改
  • 消息认证码: HMAC 保护数据完整性
  • 密钥衍生: HKDF 从共享秘密生成会话密钥

我的选择:SHA-256 和 SHA-384

算法 输出长度 安全性 适用场景
SHA-1 160 位 已破解 已禁用,不要用
SHA-256 256 位 安全 TLS 1.3 默认
SHA-384 384 位 安全 高安全场景
SHA-512 512 位 安全 性能开销大,少用
警告: 2017 年 Google 成功碰撞了 SHA-1。任何依赖 SHA-1 的证书和协议都应废弃。我在一个遗留项目中见过 SHA-1 的证书,当场就让人换了。
// 示例:HMAC-SHA256
key = 对称密钥  // 注意:HMAC 的密钥不是哈希算法的密钥
message = 待验证数据
hmac = HMAC_SHA256(key, message)
// 接收方用同样的 key 和 message 计算 HMAC,比对是否一致
避坑指南: 我曾经在 HMAC 计算时搞错了 key 的长度。HMAC 会自动处理,但如果 key 太短,会补零;太长,会被哈希。最好用固定长度的 key。

三者如何配合?一张图看懂

你看,对称加密负责传输,非对称加密负责密钥交换和身份认证,哈希负责完整性校验。缺一个都不行。

TLS密码学基石结构图 TLS 三大密码学基石 对称加密 AES / ChaCha20 原理:同一密钥 特点:高速,适合 大量数据传输 TLS 中加密应用数据 非对称加密 RSA / ECDSA 原理:公/私钥对 特点:安全分发 速度慢 TLS 中做密钥交换和签名 哈希函数 SHA-256 / SHA-384 原理:单向摘要 特点:防篡改 固定长度输出 TLS 中做完整性校验 协商 会话密钥 计算 消息摘要 签名验证 TLS 握手流程:非对称 → 对称 + 哈希 非对称加密协商密钥 → 对称加密传输数据 → 哈希保证完整性 一个小故事 我在一个金融项目中,看到他们用了 RSA 进行密钥交换, 但数据加密用的是 AES-CBC 不带 HMAC。结果被中间人篡改数据没发现。 从那以后,我坚持:密钥交换用 ECDHE,数据加密用 AES-GCM,校验用 SHA-256。

总结一下:TLS 中它们的分工

阶段 用什么 为什么
身份认证 非对称(证书签名) 验证服务器身份,防冒充
密钥协商 非对称(ECDHE) 安全地生成共享密钥,有前向安全性
数据加密 对称(AES-GCM) 高速加密传输数据
完整性校验 哈希(SHA-256)+ HMAC 防篡改,GSM 也保证了认证

嗯,这里要再强调一下——对称加密的密钥抗不过暴力破解,非对称加密扛不住量子计算,哈希函数要小心长度扩展攻击。没有完美的算法,只有合适的组合。

我个人习惯把这三者看作一个团队:非对称是保安,负责身份验证和钥匙传递;对称是房主,负责快速开门关门;哈希是摄像头,盯着有没有被动手脚。少了谁,整个家都不安全。

好,今天的密码学基础就回顾到这里。把这些概念吃透,后面理解 TLS 握手流程会轻松很多。