4. 数据加密技术基础:对称加密、非对称加密、哈希与数字签名
加密这事儿,说白了就是给数据穿上一件只有特定人能脱下来的衣服。我做了这么多年安全,见过太多因为选错加密方式导致数据裸奔的案例。今天咱们就把四种核心加密技术掰开揉碎讲清楚。
核心认知:没有万能的加密算法,只有最适合场景的加密方案。理解每种技术的优缺点,比背下一百个算法名称更重要。
4.1 对称加密:AES 算法
对称加密,就是加密和解密用同一把钥匙。你想想看,就像你家大门,用一把钥匙锁上,也用同一把钥匙打开。AES(Advanced Encryption Standard)是目前最主流的对称加密算法。
我个人习惯用 AES-256-GCM 模式。为什么?因为 GCM 模式自带认证标签,能检测数据是否被篡改。我在项目中遇到过客户只用 AES-ECB 模式加密数据库字段,结果相同明文产生相同密文,攻击者一看就知道哪些记录是重复的——这其实是个很严重的隐私泄露。
| 特性 | AES-128 | AES-192 | AES-256 |
|---|---|---|---|
| 密钥长度 | 128 bit | 192 bit | 256 bit |
| 轮数 | 10 | 12 | 14 |
| 安全性 | 足够(除量子计算) | 高 | 极高 |
| 性能 | 最快 | 中等 | 稍慢(可接受) |
我的建议:新项目直接上 AES-256-GCM。别为了省那一点点性能去用 ECB 或 CBC 模式,安全漏洞修起来代价更大。
// Python 示例:AES-256-GCM 加密与解密
from Crypto.Cipher import AES
import os
key = os.urandom(32) # 256 位密钥
nonce = os.urandom(12) # 96 位随机数
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
plaintext = b"这是需要加密的敏感数据"
ciphertext, tag = cipher.encrypt_and_digest(plaintext)
# 解密
cipher_dec = AES.new(key, AES.MODE_GCM, nonce=nonce)
data = cipher_dec.decrypt_and_verify(ciphertext, tag)
print(data.decode()) # 输出:这是需要加密的敏感数据
4.2 非对称加密:RSA 算法
非对称加密,有两把钥匙:公钥加密,私钥解密。公钥可以公开,私钥自己藏好。这解决了对称加密最大的痛点——密钥分发问题。
RSA 是目前最经典的非对称加密算法。它的安全性基于大整数分解的数学难题。说白了,两个大质数相乘很容易,但把乘积分解回两个质数,难如登天。
嗯,这里要注意:RSA 不适合加密大量数据。为什么?因为 RSA 加密 256 字节的数据,就需要 2048 位的密钥和几百毫秒的计算时间。你想想看,如果加密一个 1MB 的文件,得等到猴年马月?
避坑指南:我曾经见过有人用 RSA 直接加密大文件,结果性能惨不忍睹。正确的做法是:用 RSA 加密 AES 的密钥,再用 AES 加密实际数据。这就是所谓的「混合加密」方案。
# Python 示例:RSA 密钥生成与混合加密
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, AES
import os
# 生成 RSA 密钥对
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
# 混合加密:用 RSA 加密 AES 密钥
aes_key = os.urandom(32)
cipher_rsa = PKCS1_OAEP.new(RSA.import_key(public_key))
encrypted_aes_key = cipher_rsa.encrypt(aes_key)
# 用 AES 加密实际数据
cipher_aes = AES.new(aes_key, AES.MODE_GCM)
ciphertext, tag = cipher_aes.encrypt_and_digest(b"实际业务数据")
4.3 哈希算法:SHA-256
哈希算法,不是加密,是摘要。它把任意长度的数据,变成固定长度的「指纹」。SHA-256 输出 256 位(32 字节)的哈希值。关键特性:不可逆、抗碰撞、雪崩效应。
不可逆是什么意思?就是你从哈希值永远推不出原始数据。抗碰撞,就是很难找到两个不同数据有相同哈希值。雪崩效应,就是输入改一个比特,输出完全变样。
我在项目中遇到过有人用 MD5 做密码存储,结果被彩虹表一锅端。后来全部迁移到 SHA-256 + 盐值(salt)的方案。记住:存密码永远不要只存哈希,一定要加盐。
# Python 示例:SHA-256 哈希 + 盐值
import hashlib
import os
password = b"my_secure_password"
salt = os.urandom(16) # 随机盐值
# 加盐哈希
hash_obj = hashlib.pbkdf2_hmac('sha256', password, salt, 100000)
hash_hex = hash_obj.hex()
# 验证时:用相同的盐值和迭代次数重新计算,比对哈希值
print(f"盐值: {salt.hex()}")
print(f"哈希: {hash_hex}")
重要提醒:SHA-256 用于完整性校验(比如文件下载后的校验),但不要用于密码存储。密码存储请用 bcrypt、scrypt 或 Argon2 等专门设计的慢哈希算法。
4.4 数字签名与证书
数字签名,就是用私钥对数据的哈希值进行签名,别人用公钥验证。它解决三个问题:身份认证(你是谁)、完整性(数据被改过没)、防抵赖(你不能说不是你签的)。
数字证书,就是 CA(证书颁发机构)给你发的「电子身份证」。证书里包含你的公钥、身份信息、CA 的签名。浏览器信任 CA,CA 信任你,这就是信任链。
我曾经帮一家金融公司排查过中间人攻击。攻击者伪造了服务器证书,客户端没有验证证书链,直接信任了。结果所有 HTTPS 流量都被劫持。从那以后,我每次做安全审计,第一件事就是检查证书验证逻辑。
| 概念 | 作用 | 类比 |
|---|---|---|
| 数字签名 | 用私钥签名,公钥验证 | 手写签名 + 印章 |
| 数字证书 | 绑定公钥与身份 | 身份证 + 公安局盖章 |
| CA | 签发和管理证书 | 公安局 |
| 证书链 | 从根 CA 到终端证书的信任传递 | 上级公安局 → 下级公安局 → 你 |
# Python 示例:使用 RSA 进行数字签名与验证
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
# 签名方
private_key = RSA.generate(2048)
message = b"这是一份需要签名的合同"
h = SHA256.new(message)
signature = pkcs1_15.new(private_key).sign(h)
# 验证方
public_key = private_key.publickey()
try:
pkcs1_15.new(public_key).verify(h, signature)
print("签名验证通过,数据完整且来源可信")
except (ValueError, TypeError):
print("签名验证失败,数据可能被篡改")
实战建议:在微服务架构中,服务间通信建议使用 mTLS(双向 TLS)。每个服务都有自己的证书,既验证对方身份,又加密通信。我主导过的几个金融项目都是这么做的,效果很好。
4.5 四种技术的协同工作
实际项目中,这四种技术很少单独使用。我给你画个典型场景:
- HTTPS 握手:服务器出示数字证书(含公钥),客户端验证证书链
- 密钥交换:客户端用服务器公钥加密一个临时 AES 密钥,发送给服务器
- 对称加密通信:双方用这个 AES 密钥加密后续所有数据
- 完整性校验:每条消息附带 SHA-256 哈希值,接收方验证数据是否被篡改
- 数字签名:关键操作(如支付指令)额外用私钥签名,确保不可抵赖
你看,一个完整的 HTTPS 连接,就把对称加密、非对称加密、哈希、数字签名全用上了。这就是为什么我说「没有万能算法,只有最佳组合」。
最后提醒:加密算法本身通常没问题,出问题的大多是实现方式。密钥管理、随机数生成、证书验证——这些环节才是真正的安全短板。我见过太多「算法选对了,实现全错了」的案例。