Luke a Pro

Luke Sun

Developer & Marketer

🇺🇦
EN||

对称加密 vs 非对称加密:为什么两者都需要

| , 5 minutes reading.

1. 为什么要关心这个问题?

这是一个难题:你想给一个素未谋面的人发送加密消息,通过一个任何人都可以窃听的不受信任的网络。

如果你用 AES,你们俩需要相同的密钥。但你如何安全地共享这个密钥… 而不需要已经有一个安全通道?

这就是密钥分发问题,它困扰了密码学家几个世纪。解决方案——非对称加密——从根本上改变了安全通信的工作方式。但它带来的权衡意味着我们仍然需要两种方法。

2. 定义

对称加密: 双方使用相同的密钥进行加密和解密。

  • 例子:AES、ChaCha20、3DES
  • 类比:一把物理锁,双方都有相同的钥匙

非对称加密: 每一方都有一个密钥对——公钥(可共享)和私钥(保密)。

  • 例子:RSA、ECC、ElGamal
  • 类比:有投递口的邮箱——任何人都可以投递邮件(公钥),只有主人可以取出(私钥)

3. 根本区别

对称:相同的密钥,相同的问题

Alice                                    Bob
  │                                       │
  │  密钥: 🔑                              │  密钥: 🔑
  │                                       │
  ├──── Encrypt(message, 🔑) ────────────►│
  │           密文                        │
  │                                       ├── Decrypt(密文, 🔑)
  │                                       │        = 消息

问题: Alice 和 Bob 是如何都得到密钥 🔑 的?

  • 当面见面?无法扩展。
  • 通过网络发送?Eve 会截获它。
  • 使用另一个加密通道?你也需要那个通道的密钥。

非对称:不同的密钥,不同的角色

Alice                                    Bob
  │                                       │
  │  拥有: Bob 的公钥 📬                   │  拥有: 私钥 🔐
  │                                       │       公钥 📬
  │                                       │
  ├──── Encrypt(message, 📬) ────────────►│
  │           密文                        │
  │                                       ├── Decrypt(密文, 🔐)
  │                                       │        = 消息

解决方案: Bob 公开发布他的公钥 📬。Eve 可以看到——没关系!只有 Bob 的私钥 🔐 能解密用 📬 加密的消息。

4. 性能:房间里的大象

非对称加密解决了密钥分发问题,但引入了巨大的性能损失。

操作对称 (AES-256)非对称 (RSA-2048)
加密速度~1 GB/s~1 MB/s
相对速度1x慢约 1000 倍
等效安全性的密钥大小256 位2048 位

为什么非对称这么慢?

对称加密使用简单操作:异或、位移、替换表。

非对称加密使用复杂的数学运算:巨大数字的模幂运算(RSA)或椭圆曲线点乘法(ECC)。

# 对称:简单操作重复执行
for round in range(10):
    state = substitute(state)
    state = shift_rows(state)
    state = mix_columns(state)
    state = add_round_key(state, key)

# 非对称:繁重的数学运算
ciphertext = (message ** public_exponent) % modulus
# 其中 modulus 是一个 2048 位的数字!

5. 真实系统:混合加密

现实世界的系统不在对称和非对称之间选择——它们同时使用两者

混合方法

┌─────────────────────────────────────────────────────────┐
│ 1. 密钥交换(非对称)                                    │
│    - 生成随机对称密钥(会话密钥)                        │
│    - 用接收者的公钥加密会话密钥                          │
│    - 发送加密后的会话密钥                                │
├─────────────────────────────────────────────────────────┤
│ 2. 数据传输(对称)                                      │
│    - 用会话密钥加密实际数据(AES)                       │
│    - 对大量数据来说快得多                                │
└─────────────────────────────────────────────────────────┘

TLS 握手示例

客户端                                   服务器
  │                                        │
  │ ──── ClientHello ─────────────────────►│
  │                                        │
  │ ◄──── ServerHello + 证书 ────────────  │
  │       (包含服务器公钥)                │
  │                                        │
  │ ──── 密钥交换 ────────────────────────►│
  │      (用服务器公钥加密)              │
  │                                        │
  │ ◄════ 加密数据 (AES-GCM) ═════════════►│
  │       (使用派生的会话密钥)           │

为什么这样有效:

  1. 非对称加密仅用于密钥交换一次(或几次)
  2. 对称加密处理大量数据传输
  3. 你得到了两全其美:安全的密钥分发 + 快速的数据加密

6. 密钥分发问题已解决

非对称密码学之前(1976年前)

要与 N 个人安全通信:
- 你需要 N 个不同的对称密钥
- 每个密钥必须安全交换(当面、可信信使)
- 密钥管理在网络中以 O(N²) 增长

10 人 = 需要 45 个密钥对
100 人 = 需要 4,950 个密钥对
1,000 人 = 需要 499,500 个密钥对

非对称密码学之后

要与 N 个人安全通信:
- 每个人有一个密钥对
- 公钥可以公开分发
- 密钥管理以 O(N) 增长

10 人 = 10 个密钥对
100 人 = 100 个密钥对
1,000 人 = 1,000 个密钥对

7. 何时使用哪种

在以下情况使用对称加密:

  • 双方已经共享一个秘密
  • 加密静态数据(文件、数据库)
  • 需要高性能
  • 你控制通信的两端

在以下情况使用非对称加密:

  • 各方之前从未通信过
  • 需要数字签名(不可否认性)
  • 分发会话密钥
  • 验证身份(证书)

在以下情况使用混合:

  • 通过不受信任的网络进行安全通信
  • 为他人加密大量数据
  • 构建任何现实世界的安全通信系统

8. 常见误区

误区现实
”非对称比对称更安全”它们有不同的用途;两者都可以是安全的
”什么都用 RSA 就行”RSA 慢约 1000 倍且有大小限制
”256 位 AES = 256 位 RSA 安全性”不对!AES-256 ≈ RSA-15360 的安全级别
”公钥可以解密”公钥加密或验证;私钥解密或签名

安全级别对等表

对称RSAECC
80 位1024 位160 位
128 位3072 位256 位
256 位15360 位512 位

这就是为什么 ECC 很受欢迎——它用更小的密钥达到与 RSA 相同的安全性。

9. 代码示例:混合加密

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

def hybrid_encrypt(plaintext: bytes, recipient_public_key) -> dict:
    # 1. 生成随机 AES 密钥(对称)
    aes_key = AESGCM.generate_key(bit_length=256)

    # 2. 用 AES 加密数据(快)
    nonce = os.urandom(12)
    aesgcm = AESGCM(aes_key)
    ciphertext = aesgcm.encrypt(nonce, plaintext, None)

    # 3. 用 RSA 加密 AES 密钥(非对称)
    encrypted_key = recipient_public_key.encrypt(
        aes_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    return {
        'encrypted_key': encrypted_key,
        'nonce': nonce,
        'ciphertext': ciphertext
    }

def hybrid_decrypt(encrypted_data: dict, private_key) -> bytes:
    # 1. 用 RSA 解密 AES 密钥
    aes_key = private_key.decrypt(
        encrypted_data['encrypted_key'],
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    # 2. 用 AES 解密数据
    aesgcm = AESGCM(aes_key)
    plaintext = aesgcm.decrypt(
        encrypted_data['nonce'],
        encrypted_data['ciphertext'],
        None
    )

    return plaintext

10. 本章小结

三点要记住:

  1. 对称快,非对称解决密钥分发。 对批量数据使用对称,对密钥交换使用非对称。真实系统两者都用。

  2. 混合方法是标准。 TLS、PGP 以及几乎所有安全通信协议都使用非对称密码学来交换对称密钥。

  3. 不同类型的密钥大小不可比较。 AES-256 提供的安全性大致等于 RSA-15360 或 ECC-512。这就是为什么 ECC 越来越流行——更小的密钥,相同的安全性。

11. 下一步

我们多次提到哈希但没有完整解释它。哈希是加密吗?(剧透:不是。)

在下一篇文章中,我们将探讨:哈希函数实际上做什么,为什么它不是加密,以及存储密码的正确方式。