第2章:常见加密算法在数据库中的应用:AES、RSA、SM4对比归纳总结
聊到数据库加密,很多朋友第一反应就是「用什么算法?」。我见过不少项目,选型阶段就在AES、RSA、SM4之间反复横跳,一会儿说AES标准,一会儿说RSA能签名,一会儿又听说SM4是国标。说白了,没有一种算法是万能的。我个人习惯是先明确场景,再看参数,最后敲定方案。
先给你一张对比总表,读完本章再回来看,会很有感觉。
2.1 AES:数据库加密的默认选择
AES是目前数据库领域使用最广泛的对称加密算法。为什么?说白了就是快、稳、支持完善。我测过,AES-128比AES-256快大约40%,但安全强度在大多数场景下已经足够。
我记得有一次帮客户调优加密审计日志,他们一开始用的是AES-256-CBC。查询加密字段时,页面加载要等十几秒。我一查,问题出在密钥推导上——每次查询都重新算一遍密钥。加了个密钥缓存层,速度直接翻了3倍。
AES关键参数表
| 参数项 | 推荐值 | 说明 |
|---|---|---|
| 密钥长度 | 128-bit / 256-bit | 128-bit足够防暴力破解;256-bit应对更高安全等级 |
| 工作模式 | GCM(推荐)/ CBC | GCM自带认证,防篡改;CBC需要额外做完整性校验 |
| 填充方案 | PKCS7 | GCM模式下不需要填充 |
| 硬件加速 | AES-NI指令集 | 现代CPU普遍支持,务必启用 |
在数据库里怎么用AES?以MySQL为例,直接用内置函数就行:
-- 加密写入
INSERT INTO audit_log (encrypted_data)
VALUES (AES_ENCRYPT('敏感审计内容', 'your-encryption-key'));
-- 解密查询
SELECT AES_DECRYPT(encrypted_data, 'your-encryption-key')
FROM audit_log WHERE id = 123;
避坑提示: 用AES_ENCRYPT时一定要处理好密钥的存储。我建议用密钥管理服务(KMS),而不是直接把密钥硬编码在SQL脚本里。
你可能会问:AES-KDF(密钥派生函数)要不要用?我个人建议,如果密钥是从用户口令生成的,用PBKDF2或bcrypt做一次KDF,能把暴力破解的难度提升好几个数量级。
2.2 RSA:非对称加密的扛把子
RSA不走寻常路,它用一对密钥(公钥+私钥)。公钥加密,私钥解密,反之亦然。这玩意儿在数据库里一般不用来加密大量数据——性能太差了。你想想看,RSA加密1KB数据的时间,AES能加密几十MB了。
那RSA在数据库加密里的正确用法是什么?我碰到过不少新人,直接用RSA加密整张表,结果查询性能直接崩盘。正确的打开方式是用RSA来加密AES的密钥。这个方案叫做混合加密,在实际项目中百试百灵。
性能警示: RSA 4096-bit在单核上约5,000次/秒签名。如果你要加密10万行审计日志,用RSA直接加密,对数据库来说是噩梦。
我在项目中遇到过这么一个场景:审计日志需要跨系统传输。发送方用RSA公钥加密AES密钥,再用AES密钥加密日志数据。接收方用RSA私钥解出AES密钥,再用AES密钥解密日志。整个过程公钥在网上传输也不怕,因为只有私钥能解开。
数据库里怎么管理RSA密钥?
-- 生成RSA密钥对(示例用OpenSSL生成证书)
-- 私钥:用于解密传输来的加密密钥
-- 公钥:分发给各业务系统
-- 数据库侧存储公钥(用于验证签名)
CREATE TABLE trusted_public_keys (
id INT PRIMARY KEY,
key_name VARCHAR(64),
public_key_pem TEXT,
created_at TIMESTAMP
);
-- 使用公钥验证数据完整性(伪代码)
SELECT VERIFY_RSA_SIGNATURE(data_blob, signature, trusted_public_key_pem)
FROM audit_log;
经验分享: RSA密钥长度至少2048位。4096位更安全,但性能下降约4倍。我个人的平衡点:核心审计数据用4096位,普通日志用2048位。
2.3 SM4:国密合规的必修课
SM4是咱们国家的商用密码标准。说实话,刚接触SM4时,我觉得它跟AES差不多——都是对称加密,密钥128位,分组128位。但有几个关键差异你需要知道。
SM4最独特的地方是它的S盒设计和32轮迭代结构。我在项目中对比过SM4和AES的加解密速度,在纯软件实现下,SM4比AES慢大概15%-20%。但一旦启用了硬件加速(现在主流国产CPU都支持),差距基本可以忽略。
我曾经在金融项目里碰到一个硬性要求:所有存储个人金融信息的数据库字段,必须使用SM4加密。这是合规要求,没什么可商量的。当时我们改造了Oracle数据库的透明数据加密(TDE),把底层加密算法从AES换成了SM4,配合硬件安全模块,性能损失控制在5%以内。
SM4 vs AES核心差异速览
| 维度 | SM4 | AES-128 |
|---|---|---|
| 密钥长度 | 128位 | 128/192/256位 |
| 分组长度 | 128位 | 128位 |
| 轮数 | 32轮 | 10轮 |
| S盒 | 自定义S盒 | GF(2^8)求逆S盒 |
| 硬件加速 | 国产CPU支持 | AES-NI广泛支持 |
| 合规场景 | 国密标准(GM/T 0002) | 国际标准(FIPS 197) |
在MySQL里怎么用SM4?原生MySQL不支持,你可以通过自定义函数或插件来实现。我常用的做法是使用OpenSSL的SM4接口封装一个MySQL UDF。
-- 通过自定义插件实现SM4加密(伪代码)
-- 假设已安装 sm4_udf.so 插件
CREATE FUNCTION sm4_encrypt RETURNS STRING SONAME 'sm4_udf.so';
CREATE FUNCTION sm4_decrypt RETURNS STRING SONAME 'sm4_udf.so';
-- 加密审计日志
INSERT INTO audit_log (encrypted_msg)
VALUES (sm4_encrypt('审计内容', '128-bit-hex-key'));
-- 解密查询时注意性能
SELECT sm4_decrypt(encrypted_msg, '128-bit-hex-key')
FROM audit_log
WHERE sm4_decrypt(encrypted_msg, '128-bit-hex-key') LIKE '%敏感%';
避坑指南: 我曾经踩过一个坑——SM4的ECB模式跟AES的ECB模式在分组处理上不一样。在跨系统对接时,双方必须确认工作模式、填充方式完全一致,否则解密出来就是乱码。
2.4 三种算法如何抉择?我的实践心得
说了这么多,到底怎么选?我个人的经验是这样的:
- 数据加密(量大、高频) → 选AES-256-GCM。性能好,安全性高,有认证加密,无需额外做完整性校验。
- 密钥传输、身份认证 → 选RSA-2048或RSA-4096。保持密钥短小精悍,只加密AES密钥。
- 国密合规审查 → 选SM4。别挣扎,合规硬性要求没得选。
- 混合加密(最推荐) → RSA加密AES/SM4密钥,AES/SM4加密业务数据。既兼顾性能,又解决了密钥分发问题。
你想想看,这三个算法各有定位,但不要硬套。比如你在一个纯内网、无合规要求的审计系统里,强行上SM4+RSA双重加密,除了增加维护成本和延迟,什么好处都没有。
好了,这节课就到这。记住一句话:加密算法本身不会成为性能瓶颈,选错算法+用错方式才是。