Skip to content

MySQL 加密函数与存储

加密算法支持

常见加密算法

MySQL 支持多种加密算法,可用于不同场景的加密需求:

  • 对称加密算法:AES-128, AES-192, AES-256, DES, 3DES
  • 非对称加密算法:RSA
  • 哈希算法:MD5, SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512)
  • 其他算法:CRC32, FNV-1

算法选择建议

  • 数据加密存储:优先使用 AES-256
  • 密码存储:使用 SHA2()PASSWORD()(但不推荐使用旧版 PASSWORD())
  • 数据完整性验证:使用 SHA-256 或 SHA-512
  • 临时数据加密:可使用 AES-128 以平衡性能与安全性

加密函数使用

对称加密函数

AES 加密与解密

sql
-- AES 加密
SELECT AES_ENCRYPT('plaintext', 'encryption_key') AS encrypted_data;

-- AES 解密
SELECT AES_DECRYPT(encrypted_data, 'encryption_key') AS decrypted_data;

-- 使用初始化向量 (IV) 增强安全性
SELECT AES_ENCRYPT('plaintext', 'encryption_key', 'initialization_vector') AS encrypted_data;
SELECT AES_DECRYPT(encrypted_data, 'encryption_key', 'initialization_vector') AS decrypted_data;

DES 加密与解密

sql
-- DES 加密
SELECT DES_ENCRYPT('plaintext', 'encryption_key') AS encrypted_data;

-- DES 解密
SELECT DES_DECRYPT(encrypted_data, 'encryption_key') AS decrypted_data;

非对称加密函数

RSA 加密与解密

sql
-- 生成 RSA 密钥对
SELECT * FROM RSA_KEY_GENERATE(2048);

-- 使用公钥加密
SELECT RSA_ENCRYPT('plaintext', public_key) AS encrypted_data;

-- 使用私钥解密
SELECT RSA_DECRYPT(encrypted_data, private_key) AS decrypted_data;

哈希函数

密码哈希

sql
-- 使用 SHA-256 哈希密码
SELECT SHA2('password123', 256) AS hashed_password;

-- 使用盐值增强安全性
SELECT SHA2(CONCAT('salt_value', 'password123'), 256) AS salted_hash;

-- 使用 MySQL 内置的密码哈希函数
SELECT PASSWORD('password123') AS mysql_password_hash; -- 不推荐使用
SELECT SHA2('password123', 256) AS recommended_hash;

数据完整性验证

sql
-- 计算数据哈希值
SELECT SHA2('data_to_verify', 256) AS data_hash;

-- 验证数据完整性
SELECT CASE WHEN SHA2('data_to_verify', 256) = stored_hash THEN 'Integrity verified' ELSE 'Data corrupted' END AS integrity_check;

加密存储方案

列级加密

实现方式

sql
-- 创建包含加密列的表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    encrypted_email BLOB,
    email_iv BLOB
);

-- 插入加密数据
INSERT INTO users (username, encrypted_email, email_iv)
VALUES ('john', AES_ENCRYPT('john@example.com', 'encryption_key', RANDOM_BYTES(16)), RANDOM_BYTES(16));

-- 查询解密数据
SELECT username, AES_DECRYPT(encrypted_email, 'encryption_key', email_iv) AS email
FROM users;

最佳实践

  • 使用随机生成的初始化向量 (IV) 并存储
  • 加密密钥应安全存储,避免硬编码在应用程序中
  • 考虑使用密钥管理服务 (KMS) 来管理加密密钥
  • 对敏感列添加索引时,应考虑使用哈希索引而非明文索引

表级加密

MySQL 8.0 透明数据加密 (TDE)

sql
-- 查看 TDE 状态
SELECT * FROM performance_schema.keyring_component_status;

-- 启用 TDE 配置
[mysqld]
early-plugin-load-add = keyring_file.so
keyring_file_data = /path/to/keyring/file

-- 创建加密表空间
CREATE TABLESPACE encrypted_tablespace
ADD DATAFILE 'encrypted_tablespace.ibd'
ENCRYPTION = 'Y';

-- 在加密表空间创建表
CREATE TABLE encrypted_table (
    id INT PRIMARY KEY,
    sensitive_data VARCHAR(100)
) TABLESPACE encrypted_tablespace;

加密表空间管理

sql
-- 修改现有表使用加密表空间
ALTER TABLE existing_table TABLESPACE encrypted_tablespace;

-- 查看表的加密状态
SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS
FROM information_schema.tables
WHERE TABLE_SCHEMA = 'database_name';

应用层加密

架构设计

  1. 应用层加密流程

    • 应用程序在客户端加密数据
    • 将加密后的数据存储到 MySQL
    • 查询时从 MySQL 获取加密数据
    • 在客户端解密数据
  2. 优势

    • 数据库管理员无法直接访问明文数据
    • 可使用更灵活的加密算法
    • 密钥管理在应用层,更安全
  3. 劣势

    • 无法在数据库层面进行高效查询
    • 应用程序复杂度增加
    • 需要额外的密钥管理机制

加密密钥管理

内置密钥环插件

支持的密钥环插件

  • keyring_file:基于文件的密钥存储(适用于测试环境)
  • keyring_aws:与 AWS KMS 集成
  • keyring_hashicorp:与 HashiCorp Vault 集成
  • keyring_encrypted_file:加密的文件密钥存储

配置示例(keyring_file)

ini
[mysqld]
keyring_file_data = /var/lib/mysql-keyring/keyring_file
early-plugin-load = keyring_file.so

外部密钥管理服务

AWS KMS 集成

ini
[mysqld]
keyring_aws_conf_file = /etc/mysql/keyring_aws.conf
early-plugin-load = keyring_aws.so

HashiCorp Vault 集成

ini
[mysqld]
keyring_hashicorp_conf_file = /etc/mysql/keyring_hashicorp.conf
early-plugin-load = keyring_hashicorp.so

性能优化

加密性能影响

  • 对称加密(如 AES-256)对性能影响较小(通常 < 5%)
  • 非对称加密(如 RSA)对性能影响较大,应避免频繁使用
  • 哈希函数性能较好,适合用于数据完整性验证

优化建议

  1. 选择合适的加密算法:根据安全需求和性能要求选择平衡的算法
  2. 批量处理加密操作:减少加密函数调用次数
  3. 使用硬件加速:确保服务器支持 AES-NI 等硬件加速技术
  4. 优化查询设计:避免在 WHERE 子句中使用解密函数
  5. 合理设置密钥长度:不盲目追求过长密钥,根据实际需求选择

安全最佳实践

密钥管理

  • 定期轮换加密密钥
  • 使用不同密钥加密不同类型的数据
  • 避免将密钥存储在数据库服务器上
  • 实现密钥的访问控制和审计

加密实现

  • 永远不要硬编码加密密钥
  • 使用安全的随机数生成器生成 IV 和盐值
  • 对所有敏感数据实施加密
  • 考虑使用端到端加密方案

审计与监控

  • 监控加密密钥的使用情况
  • 审计加密和解密操作
  • 定期检查加密配置的有效性
  • 实施访问控制,限制加密函数的使用权限

常见问题(FAQ)

Q1: 什么是透明数据加密 (TDE)?

A1: 透明数据加密 (TDE) 是 MySQL 8.0 引入的一项功能,用于加密存储在磁盘上的数据文件。TDE 对应用程序透明,应用程序无需修改即可使用加密功能。TDE 主要用于防止物理数据泄露,如硬盘被盗或未经授权的物理访问。

Q2: 列级加密和表级加密有什么区别?

A2: 列级加密仅加密表中的特定列,而表级加密(如 TDE)加密整个表空间。列级加密提供更细粒度的控制,但需要在应用程序中显式调用加密和解密函数。表级加密对应用程序透明,但加密粒度较粗,无法选择性地加密特定列。

Q3: 如何安全地存储加密密钥?

A3: 加密密钥应安全存储,避免硬编码在应用程序或配置文件中。推荐使用专门的密钥管理服务 (KMS),如 AWS KMS、HashiCorp Vault 或 MySQL 内置的密钥环插件。对于生产环境,应避免使用基于文件的密钥存储,除非文件系统已加密且访问权限严格控制。

Q4: 加密会对 MySQL 性能产生多大影响?

A4: 加密对 MySQL 性能的影响取决于使用的加密算法和实现方式。一般来说,对称加密(如 AES-256)对性能影响较小(通常在 5% 以内),而非对称加密(如 RSA)对性能影响较大。使用硬件加速(如 AES-NI)可以显著提高加密性能。

Q5: 如何选择合适的加密算法?

A5: 选择加密算法时应考虑安全需求、性能要求和兼容性。对于数据加密存储,优先使用 AES-256;对于密码存储,使用 SHA-256 或更安全的哈希算法;对于数据完整性验证,使用 SHA-256 或 SHA-512。应避免使用已被证明不安全的算法,如 MD5 和 SHA-1 用于安全敏感场景。

Q6: 如何实现加密数据的高效查询?

A6: 加密数据的高效查询是一个挑战,因为数据库无法直接对加密数据进行索引和比较。解决方案包括:

  • 使用哈希索引:对加密列的哈希值创建索引
  • 部分加密:仅加密敏感部分,保留可查询的非敏感部分
  • 同态加密:允许在加密数据上直接进行计算(目前 MySQL 不原生支持)
  • 搜索able 加密:专门设计用于支持加密数据查询的加密方案

Q7: 如何处理加密密钥轮换?

A7: 加密密钥轮换是安全最佳实践,应定期进行。实现密钥轮换的步骤包括:

  1. 生成新的加密密钥
  2. 使用新密钥重新加密所有数据
  3. 验证新密钥加密的数据可以正常访问
  4. 安全销毁旧密钥
  5. 更新所有相关系统的密钥配置

对于大量数据,密钥轮换可能需要较长时间,建议在低峰期进行,并考虑使用批量处理方式。

Q8: 外部密钥管理服务与内置密钥环插件相比有什么优势?

A8: 外部密钥管理服务(如 AWS KMS、HashiCorp Vault)相比内置密钥环插件具有以下优势:

  • 更强大的密钥管理功能,如自动密钥轮换、密钥版本控制
  • 更严格的访问控制和审计
  • 更高的可用性和可靠性
  • 支持多区域和多环境部署
  • 与其他云服务或企业系统的集成能力

对于生产环境,特别是对安全性要求较高的场景,推荐使用外部密钥管理服务。