MySQL不自带字段级加密,需应用层加密(如AES-256-GCM)、列级权限控制(视图脱敏+字段权限限制)、TDE保护静态数据、审计日志过滤协同实现。

MySQL 本身不自带字段级加密功能,保护敏感字段(如身份证号、手机号、银行卡号)需结合应用层控制与数据库层策略协同实现,核心思路是“数据落地前加密、访问时最小权限、传输中全程加密”。
应用层加密:最常用且可控的方式
在数据写入 MySQL 前,由应用程序完成加密,数据库只存储密文。推荐使用行业标准算法(如 AES-256-GCM),密钥由应用统一管理,不存于数据库。
- 避免用 MySQL 内置函数(如 AES_ENCRYPT())做主加密逻辑——密钥易泄露、无安全随机 IV、不支持认证加密
- 推荐使用语言原生加密库:Python 用 cryptography,Java 用 javax.crypto,Go 用 crypto/aes
- 加密时务必使用唯一随机 IV,并与密文一同存储(如拼接或另存字段),解密时严格校验完整性
列级权限控制:限制谁能看到明文
即使数据未加密,也可通过 MySQL 权限系统隔离敏感字段访问范围。
- 创建专用视图(VIEW),对敏感字段做脱敏处理(如 CONCAT(LEFT(id_card,3), '****', RIGHT(id_card,4))),仅授权业务账号查视图
- 对真实表执行 REVOKE SELECT (phone, id_card) ON db.user_table FROM 'app_user'@'%',禁止直接查敏感列
- 配合角色(ROLE)管理权限,例如 role_analyst 只能查脱敏视图,role_admin 才有全字段权限
透明数据加密(TDE):保护静态数据文件
TDE 加密的是整个表空间(.ibd 文件),防止磁盘被盗或备份泄露,但不保护字段级内容,运行时仍以明文加载到内存。
- MySQL 5.7+ 企业版原生支持 TDE;社区版可通过 Percona Server 或 MariaDB 替代方案启用
- 启用后需配置密钥环插件(keyring_file 或 keyring_okv),密钥文件必须设严格文件权限(如 600)并独立存放
- TDE 对性能影响较小(约 3%~5%),但无法替代应用层加密——它防不了 DBA 直接查表
审计与脱敏日志:堵住非查询类泄露路径
慢查询日志、通用查询日志、错误日志可能意外记录敏感数据,需主动过滤。
- 禁用 general_log(生产环境严禁开启),确需审计时用 MySQL Enterprise Audit 或 Percona Audit Log
- 设置 log_error_verbosity = 2,避免错误日志打印 SQL 全文;对含敏感字段的 INSERT/UPDATE 语句,应用层应提前抹除值再打日志
- 备份脚本中禁用 --complete-insert,改用 --skip-extended-insert 防止单行 INSERT 含大量明文
不复杂但容易忽略:加密不是一劳永逸,要定期轮换密钥、监控异常解密失败、审计权限变更记录。真正安全的数据链路,始于代码里的加密调用,止于 DBA 看不到明文的那一刻。










