数据库加密基础:概念、分类与常见算法
聊数据库加密之前,得先搞清楚一个根本问题——加密到底在防谁?
金融行业的数据,说白了就是钱和人的信息。客户姓名、身份证号、银行卡号、交易流水,随便一个字段泄漏都是大事故。加密的作用就是把「明文」变成「密文」,即使硬盘被人搬走了、备份被人拷了,对方看到也是一堆乱码。我参与过的审计日志项目里,光是字段级加密这一项,就能挡住90%以上的配置失误泄漏。
好,直接上干货。先看加密的三要素:算法、密钥、模式。算法决定转换规则,密钥决定唯一性,模式决定怎么处理大数据块。这三者搭配起来,才构成一个完整加密方案。
加密分类:从两个维度切
分类方法有很多,我习惯从两个最关键的维度去看:密钥体系和加密粒度。
| 维度 | 分类 | 代表算法/方案 | 适用场景 |
|---|---|---|---|
| 密钥体系 | 对称加密 | AES, 3DES, SM4 | 大数据量、数据库内部字段加密 |
| 密钥体系 | 非对称加密 | RSA, ECC, SM2 | 密钥分发、数字签名、少量数据 |
| 加密粒度 | 全库加密 | TDE(透明数据加密) | 备份文件、静态数据保护 |
| 加密粒度 | 表级加密 | Oracle TDE 表空间 | 指定业务表防护 |
| 加密粒度 | 字段级加密 | AES-256 + 应用层密钥 | 身份证、手机号等高敏感属性 |
个人习惯:金融审计日志场景,我几乎只推荐字段级加密配合对称算法。全库加密太粗暴,查询性能下降明显;表级加密又不够灵活。字段级加密让审计只对敏感列解密,性能影响可控,合规也容易过。
常见算法速览
算法不是越多越好,关键是选对并理解它的弱点。下面这几个是我实际项目中接触最多的。
- AES(高级加密标准):当前对称加密的王者。密钥长度128/192/256,我更推荐AES-256。为什么呢?128位抗撞库够用,但金融审计日志通常是超长期保留(5~10年),我建议直接上256位,不留隐患。
- SM4(国密标准):国内金融必须对齐。本质上和AES对标,128位分组,32轮迭代。我在央行的一个审计项目里就硬性要求使用SM4代替AES,代码实现不难,但密钥管理库要换一套。
- RSA(非对称):常用于加密密钥本身或数字签名。2048位起步,一次最多加密明文长度不能超过密钥位数减11字节(比如2048位只能加密256-11=245字节)。做个证书、交换个会话密钥还行,直接加密大字段就是自讨苦吃。
- ECC(椭圆曲线):比RSA同安全强度下密钥短很多,256位ECC ≈ 3072位RSA。我在移动端审计APP数据回传时用过ECC做签名,效率确实漂亮。
我曾经踩过的坑:有一回用AES-128做字段级加密,测试环境一切正常。上线后业务方说某个查询慢了10倍。排查发现他们用「AES加密列」做了LIKE模糊匹配,导致每次查询都要全表解密再过滤。这就是典型的「只加密不考虑查询需求」——后来我们改用部分明文保留+加密+哈希索引的三层方案才解决。
核心流程:加密/解密怎么跑
无论你选哪种算法,操作流程都差不多。以最常见的字段级加密为例:
- 密钥生成:用安全的随机数生成器(比如
/dev/urandom)产生一个256位密钥。 - 密钥存储:密钥不能和密文放一起。我习惯用专门的密钥管理服务(KMS),或者至少存到HSM硬件安全模块里。
- 加密:取明文数据 + 密钥 + IV(初始化向量),跑AES-256-CBC模式,输出密文(Base64编码方便存储)。
- 解密:从存储中取出密文,用同样的密钥和IV还原明文。
- 审计钩子:在加密/解密操作前后,自动记录日志:谁、何时、操作了什么数据的什么字段。这就是审计日志的来源。
# Python 示例:字段级 AES-256-CBC 加密/解密(仅演示)
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64, os
key = os.urandom(32) # 256位密钥
iv = os.urandom(16) # IV,每次加密随机生成
def encrypt_field(plaintext: str) -> str:
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
ct_bytes = cipher.encrypt(pad(plaintext.encode(), AES.block_size))
return base64.b64encode(iv + ct_bytes).decode()
def decrypt_field(ciphertext: str) -> str:
raw = base64.b64decode(ciphertext)
iv = raw[:16]
ct = raw[16:]
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
pt = unpad(cipher.decrypt(ct), AES.block_size)
return pt.decode()
细节注意:上面的IV拼接方式只适合演示。生产环境一定要对密钥进行访问控制,IV必须存但不能泄漏,每次加密使用新IV(随机化至关重要)。另外,Base64编码会让密文长度膨胀约1/3,数据库字段类型推荐用
VARBINARY 或 BLOB 减少空间浪费。
一张图看懂数据库加密体系
这张图基本涵盖了数据库加密的三个主要维度:按密钥体系分、按加密粒度分、按常见算法分。三者交叉选择就构成了实际的加密方案。金融审计日志项目里,我个人偏好「对称+字段级+定制密钥管理」的组合,既能满足合规审计要求,又不会把性能搞崩。
记住一点:算法是骨架,密钥管理才是灵魂。密钥丢了,再强的算法也是白搭。