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

各位同学,欢迎来到《Android SSL/TLS 安全通信实战》的第二讲。在深入 SSL/TLS 协议之前,我们得先把地基打牢。密码学,说白了就是 SSL/TLS 的「灵魂」。你想想看,如果没有这些基础算法,整个互联网的安全体系就垮了。

我个人习惯,在讲任何协议之前,先带大家回顾一下密码学的四大金刚:对称加密、非对称加密、哈希函数、数字签名。这四样东西,你在日常开发中几乎天天都在用,只是可能没意识到而已。

核心观点: SSL/TLS 是「协议」,而密码学是「工具」。协议负责怎么用,工具负责怎么算。不懂工具,协议就是空中楼阁。

密码学四大基础 对称加密 AES / DES / 3DES 非对称加密 RSA / ECC / DH 哈希函数 SHA-256 / MD5 数字签名 RSA签名 / ECDSA SSL/TLS 握手阶段:混合使用以上四种技术 SSL/TLS 并非只用一种加密,而是「混合加密」策略 非对称加密传递对称密钥 → 对称加密加密数据 哈希函数保证完整性 → 数字签名保证身份

1. 对称加密:又快又简单,但有个致命问题

对称加密,顾名思义,加密和解密用的是同一把钥匙。就像你家里的门锁,用钥匙锁门,也用同一把钥匙开门。

常见的对称加密算法有:

  • AES(Advanced Encryption Standard)—— 目前最主流,推荐使用 AES-256
  • DES(Data Encryption Standard)—— 太老了,密钥只有56位,现在基本被淘汰
  • 3DES(Triple DES)—— DES 的加强版,但效率低,也不推荐了

我的经验: 在 Android 开发中,我建议直接用 AES-GCM 模式。为什么?因为它自带认证加密,能同时保证机密性和完整性。我曾经见过有人用 AES-CBC 模式,结果忘了做 HMAC 校验,被 padding oracle 攻击打得满地找牙……嗯,从那以后我就只用 GCM 了。

对称加密最大的优点就是快。加密几 MB 的数据,几乎感觉不到延迟。但缺点也很明显——密钥怎么安全地传给对方?你想想看,如果密钥在传输过程中被截获,那加密就等于白做了。

这就是为什么 SSL/TLS 不只用对称加密。它先用非对称加密来安全地交换对称密钥,然后再用对称加密来加密实际数据。这叫「混合加密」,后面我们会详细讲。

2. 非对称加密:公钥私钥,天生一对

非对称加密解决了密钥分发的问题。它有一对密钥:公钥(公开)和私钥(保密)。公钥加密的数据,只有私钥能解密;反过来,私钥加密的数据,只有公钥能解密。

常见的非对称加密算法:

  • RSA —— 最经典,基于大整数分解难题。密钥长度至少 2048 位
  • ECC(椭圆曲线密码学)—— 更高效,256 位的 ECC 相当于 3072 位的 RSA
  • DH(Diffie-Hellman)—— 用于密钥交换,不是用来加密数据的
特性 对称加密 非对称加密
密钥数量 1 个(共享密钥) 2 个(公钥 + 私钥)
速度 非常快 慢(比对称加密慢 1000 倍以上)
典型用途 加密大量数据 密钥交换、数字签名
安全性基础 密钥保密 私钥保密 + 数学难题

注意: 非对称加密虽然解决了密钥分发问题,但它慢啊!你想想看,如果整个 HTTPS 请求都用 RSA 加密,那服务器得累死。所以实际中,非对称加密只用来加密一个「对称密钥」,剩下的数据交给对称加密处理。

3. 哈希函数:不是加密,是「指纹」

哈希函数,很多人误以为它是加密。其实不是。哈希函数是单向的——你把任意长度的数据丢进去,它吐出一个固定长度的「摘要」。而且你没法从摘要反推出原始数据。

常见的哈希算法:

  • SHA-256 —— 输出 256 位,目前最安全,推荐使用
  • SHA-1 —— 输出 160 位,已经被破解,别用了
  • MD5 —— 输出 128 位,早就不安全了,碰撞攻击很容易

哈希函数在 SSL/TLS 中干什么用?

  • 验证数据完整性:传输过程中有没有被篡改?一算哈希就知道
  • 生成密钥材料:TLS 握手时,用哈希函数来派生会话密钥
  • 数字签名的第一步:先对消息做哈希,再对哈希值签名

关键点: 哈希函数是「防篡改」的,不是「防窃听」的。如果有人改了数据,哈希值会变。但哈希本身不加密,原始数据还是可见的。

我记得有一次做安全审计,发现某个 App 用 MD5 来校验下载的文件完整性。我当时就笑了——MD5 的碰撞攻击在 2004 年就已经被公开了,随便改个文件还能保持 MD5 不变。嗯,后来我让他们全部换成了 SHA-256。

4. 数字签名:证明「你是谁」和「你没撒谎」

数字签名,说白了就是「带身份认证的哈希」。它解决了两个问题:

  1. 身份认证: 这消息真的是你发的吗?
  2. 不可否认性: 你发了消息之后,不能反悔说没发过

数字签名的流程是这样的:

  • 发送方:对消息做哈希 → 用私钥加密哈希值 → 得到签名
  • 接收方:对消息做哈希 → 用公钥解密签名 → 对比两个哈希值

如果哈希值一致,说明消息没被改过,而且确实是私钥持有者签的。

避坑指南: 我曾经在项目中遇到过一个问题——有人直接用 RSA 加密整个消息,以为这就是签名。不对!签名是对哈希值加密,不是对原始消息加密。这两者有本质区别。加密是为了保密,签名是为了认证。千万别搞混了。

在 SSL/TLS 中,数字签名出现在两个地方:

  • 证书验证:CA 用私钥签名你的证书,浏览器用 CA 的公钥验证
  • 握手阶段:服务器用私钥签名某些握手参数,客户端用公钥验证

5. 这四样东西怎么配合?

你可能会问:SSL/TLS 为什么需要这四种技术?不能只用一种吗?

答案是:每种技术都有自己的短板,组合起来才能互补。

  • 对称加密 快,但密钥分发难 → 用非对称加密来解决
  • 非对称加密 能安全交换密钥,但慢 → 只用来加密对称密钥
  • 哈希函数 能检测篡改,但不能认证身份 → 用数字签名来补
  • 数字签名 能认证身份,但计算量大 → 只对哈希值签名,不是对整个消息

你看,这就是工程上的智慧。没有银弹,只有合理的组合。

一句话总结: SSL/TLS 用非对称加密来安全地协商对称密钥,用对称加密来加密实际数据,用哈希函数来保证数据完整性,用数字签名来验证通信双方的身份。四者缺一不可。

好了,密码学基础就回顾到这里。这些东西看起来简单,但实际用起来坑不少。后面讲 SSL/TLS 握手协议的时候,你会看到这些算法是如何被组合使用的。到时候我们再深入细节。


公众号:蓝海资料掘金营,微信deep3321