常用加密算法:对称、非对称与哈希

老实说,加密算法这玩意儿,刚入门时很容易被各种术语绕晕。我自己带团队做 API 加密适配那会儿,最头疼的就是新人分不清「加密」和「签名」的区别。这一章我们就一把捋清楚三个核心家族:AES、RSA 和 SHA。嗯,这都是你天天打交道的东西。

对称加密:AES 为什么能扛大旗

对称加密,说白了就是「一把钥匙开一把锁」—— 加密和解密用同一个密钥。快,是真快,但分发密钥要小心。

我项目中用得最多的对称算法就是 AES。它取代了老旧的 DES 和 3DES。AES 支持三种密钥长度:128 位、192 位、256 位。长度越长越安全,但速度会慢一点。实际项目中我建议你用 AES-256-GCM,既有认证又防篡改。

特性 AES-128 AES-192 AES-256
密钥长度 16 字节 24 字节 32 字节
安全强度 高 更高 极高
性能 最快 中等 较慢(但仍很快)
适用场景 数据库字段加密 一般 API 参数加密 高敏感数据(如支付、医疗)

代码示例 – Python 中使用 AES-256-GCM 加密

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

key = AESGCM.generate_key(bit_length=256)  # 32 字节密钥
aesgcm = AESGCM(key)

nonce = os.urandom(12)  # 96 位随机数,每次加密必须不同
plaintext = b"这是一段敏感数据"
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
print(f"加密结果(hex): {ciphertext.hex()}")

我的经验: 密钥不要硬编码在代码里。我用过 Vault 和 KMS 来管理密钥,强烈推荐。另外 nonce 绝不能重复用,否则 GCM 模式会裂开。

非对称加密:RSA 的公私钥哲学

非对称加密的核心是「公钥加密,私钥解密」。你想想看,你公开了公钥,别人用公钥加密数据发给你,只有你能用私钥解开。这解决了对称加密的密钥分发难题。

RSA 是最经典的非对称算法。我做过一个跨系统加密方案,系统 A 用系统 B 的公钥加密请求体,系统 B 用私钥解密,全程不需要共享密钥。但 RSA 性能差,不适合加密大数据。一般只用来加密对称密钥(称为「密钥封装」),或用它做数字签名。

RSA 密钥长度对比

密钥长度 安全等级(对标 AES) 加密速度 建议
1024 位 约 80 位 快 已废弃,不要用了
2048 位 约 112 位 中等 当前最低标准
4096 位 约 128 位 较慢 推荐用于高安全场景

避坑: 我曾经踩过一个坑——RSA 加密的明文长度不能超过密钥长度减去一定开销(OAEP 填充下约 41 字节)。如果你直接拿大数据去 RSA 加密,会报错。解决方案是先 AES 加密数据,再用 RSA 加密 AES 密钥。

代码示例 – RSA 密钥生成与加解密(Python)

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes

# 生成 2048 位密钥对
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048
)
public_key = private_key.public_key()

# 加密
plaintext = b"Hello from RSA"
ciphertext = public_key.encrypt(
    plaintext,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)

# 解密
decrypted = private_key.decrypt(
    ciphertext,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
print(decrypted)  # b"Hello from RSA"

哈希算法:SHA 家族与不可逆性

哈希跟加密不一样。它是单向的:你输入任何长度的数据,输出固定长度的摘要。你不能从摘要反推出原文。我们常用它做密码存储、数据完整性校验和数字签名。

SHA(安全哈希算法)目前主流是 SHA-2 家族(SHA-256、SHA-384、SHA-512)。SHA-1 已经被破解,别用了。而 SHA-3 是最新标准,不过还没大规模普及。

我个人习惯,在数据库适配加密场景中,一般用 SHA-256 做数据完整性校验。比如你先算文件的 SHA-256 哈希,接收方再算一次,比对看是否被篡改。我还做过一个系统,用 SHA-256 对 API 请求参数签名,防止中间人篡改。

哈希与加密的区别

特性 哈希(SHA) 对称加密(AES) 非对称加密(RSA)
方向 单向不可逆 双向可逆 双向可逆
密钥 无密钥 一个共享密钥 一对公私钥
输出长度 固定(如 256 位) 与明文长度相关 与密钥长度相关
主要用途 完整性校验、密码存储 数据加密传输 密钥交换、数字签名

重点: 存储密码时不要只用 SHA-256。一定要加盐(salt),并使用慢哈希如 bcrypt、scrypt 或 Argon2。只做一次 SHA-256,彩虹表分分钟给你撞出来。

三种算法如何配合?一张图讲清

其实在一个完整的加密 API 中,三种算法常常混着用。比如 HTTPS 的 TLS 握手:用 RSA(或 ECDHE)做密钥交换,用 AES 加密后续数据,用 SHA 做消息认证。下面这张图展示了我设计统一加密 API 时的核心逻辑。

统一加密 API 核心流程 原始数据 加密/签名? (策略选择) 对称加密 AES-256-GCM 非对称加密 RSA-2048 / ECC 完整性校验(SHA-256) 安全加密数据 图例 ▄ AES 对称加密路径 ▄ RSA 非对称加密路径 ▄ SHA 完整性校验

如何统一这三种算法?

在实际的多数据库适配中,我们需要一个统一的 API 来封装不同算法的调用。比如你只有一个 encrypt() 函数,但背后根据配置自动选用 AES 或 RSA。这样做的好处是:业务层不用关心具体算法,切换数据库或安全策略时只改配置。

我建议这样设计接口:

  • 加密: 传入明文、算法类型("AES" 或 "RSA")、密钥,返回密文。
  • 解密: 对称算法直接解,非对称算法用私钥解。
  • 哈希: 纯函数,传入数据返回摘要。同时支持加盐选项。

我个人习惯在哈希函数里内置一个「盐」,比如当前时间戳杂凑后做一段固定前缀。这样即使两个用户密码相同,存到数据库的哈希值也不一样,更安全。

新手常犯的错

我见过不少同事把哈希当加密用,还说「哈希解密太慢」—— 其实你根本解不了。说白了,要搞清楚你是在做保密性(加密)还是完整性(哈希)。还有一个坑:AES 的 ECB 模式不要用。我当初第一次写加密代码就用了 ECB,被安全审计骂惨了。CBC 或 GCM 才是正解。

嗯,这一章就到这里。记住三点:对称加密快,非对称加密安全分发密钥,哈希做完整性。下一回我们聊聊如何把这些算法封装成统一的 API 接口。

最后提醒: 密钥管理比算法本身更复杂。就算你用 AES-256 加密了数据,如果密钥被泄露,等于白加密。建议配合硬件安全模块(HSM)或云 KMS 使用。