Skip to content

KingBaseES 数据加密

数据加密概述

数据加密是保护KingBaseES数据库静态数据安全的重要手段,它通过对数据库文件、表数据或特定列进行加密,防止数据在存储层面被未授权访问或窃取。数据加密主要包括透明数据加密(TDE)、列级加密、表级加密等多种方式,可以根据业务需求选择合适的加密策略。

数据加密机制

1. 透明数据加密(TDE)

透明数据加密(TDE)是指对数据库文件进行加密,对应用程序透明,无需修改应用代码。TDE主要加密:

  • 数据文件
  • 重做日志
  • 归档日志
  • 备份文件

2. 列级加密

列级加密是指对表中的特定列进行加密,适合保护敏感数据,如密码、身份证号、银行卡号等。列级加密支持多种加密算法和密钥管理方式。

3. 表级加密

表级加密是指对整个表进行加密,包括表结构和数据。表级加密提供了更细粒度的访问控制。

4. 加密算法

KingBaseES支持多种加密算法,包括:

  • 对称加密算法:AES-128, AES-256, DES, 3DES等
  • 非对称加密算法:RSA, ECDSA等
  • 哈希算法:SHA-256, SHA-384, SHA-512等
  • 密钥派生算法:PBKDF2等

透明数据加密(TDE)配置

1. 配置TDE

sql
-- 查看TDE配置
SHOW tde_enabled;
SHOW tde_key_file;
SHOW tde_cipher_algorithm;

-- 启用TDE
ALTER SYSTEM SET tde_enabled = on;
ALTER SYSTEM SET tde_key_file = '/opt/kingbase/tde/tde.key';
ALTER SYSTEM SET tde_cipher_algorithm = 'aes-256-cbc';

-- 重启数据库使TDE配置生效
-- sys_ctl restart -D /path/to/data

2. 创建TDE密钥

bash
# 创建TDE密钥目录
mkdir -p /opt/kingbase/tde
chown kingbase:kingbase /opt/kingbase/tde
chmod 700 /opt/kingbase/tde

# 生成TDE密钥
openssl rand -hex 32 > /opt/kingbase/tde/tde.key
chmod 600 /opt/kingbase/tde/tde.key
chown kingbase:kingbase /opt/kingbase/tde/tde.key

3. 创建加密表空间

sql
-- 创建加密表空间
CREATE TABLESPACE tde_tablespace
  LOCATION '/path/to/tde_tablespace'
  WITH (encryption = 'on');

-- 创建加密数据库
CREATE DATABASE tde_db
  TABLESPACE tde_tablespace
  WITH (encryption = 'on');

-- 创建加密表
CREATE TABLE tde_table (
  id serial PRIMARY KEY,
  data text
)
TABLESPACE tde_tablespace;

列级加密配置

1. 创建加密密钥

sql
-- 创建主密钥(用于加密其他密钥)
CREATE OR REPLACE FUNCTION create_master_key() RETURNS void AS $$
DECLARE
  master_key bytea;
BEGIN
  -- 生成主密钥
  master_key := gen_random_bytes(32);
  
  -- 存储主密钥(实际生产中应使用密钥管理系统)
  INSERT INTO sys_key_store (key_name, key_data, key_type)
  VALUES ('master_key', master_key, 'AES-256');
END;
$$ LANGUAGE plpgsql;

-- 执行创建主密钥函数
SELECT create_master_key();

2. 创建加密函数

sql
-- 创建加密函数
CREATE OR REPLACE FUNCTION encrypt_data(p_plaintext text, p_key_name text) RETURNS text AS $$
DECLARE
  v_key bytea;
  v_iv bytea;
  v_ciphertext bytea;
BEGIN
  -- 获取密钥
  SELECT key_data INTO v_key FROM sys_key_store WHERE key_name = p_key_name;
  
  -- 生成随机IV
  v_iv := gen_random_bytes(16);
  
  -- 加密数据
  v_ciphertext := encrypt(p_plaintext::bytea, v_key, v_iv, 'aes-256-cbc');
  
  -- 返回IV+密文(base64编码)
  RETURN encode(v_iv || v_ciphertext, 'base64');
END;
$$ LANGUAGE plpgsql;

-- 创建解密函数
CREATE OR REPLACE FUNCTION decrypt_data(p_ciphertext text, p_key_name text) RETURNS text AS $$
DECLARE
  v_key bytea;
  v_iv bytea;
  v_ciphertext bytea;
  v_plaintext bytea;
BEGIN
  -- 获取密钥
  SELECT key_data INTO v_key FROM sys_key_store WHERE key_name = p_key_name;
  
  -- 解码base64密文
  v_ciphertext := decode(p_ciphertext, 'base64');
  
  -- 提取IV(前16字节)
  v_iv := substring(v_ciphertext from 1 for 16);
  
  -- 提取实际密文
  v_ciphertext := substring(v_ciphertext from 17);
  
  -- 解密数据
  v_plaintext := decrypt(v_ciphertext, v_key, v_iv, 'aes-256-cbc');
  
  RETURN v_plaintext::text;
END;
$$ LANGUAGE plpgsql;

3. 创建加密表

sql
-- 创建包含加密列的表
CREATE TABLE users (
  id serial PRIMARY KEY,
  username varchar(50) NOT NULL,
  password_hash varchar(255) NOT NULL,
  email varchar(100) NOT NULL,
  phone_encrypted text,
  id_card_encrypted text,
  created_at timestamp DEFAULT now()
);

-- 插入加密数据
INSERT INTO users (username, password_hash, email, phone_encrypted, id_card_encrypted)
VALUES (
  'testuser',
  crypt('password123', gen_salt('bf')),
  'test@example.com',
  encrypt_data('13800138000', 'master_key'),
  encrypt_data('110101199001011234', 'master_key')
);

-- 查询解密数据
SELECT 
  id, 
  username, 
  email, 
  decrypt_data(phone_encrypted, 'master_key') as phone,
  decrypt_data(id_card_encrypted, 'master_key') as id_card,
  created_at
FROM users;

数据加密验证和测试

1. 验证TDE配置

sql
-- 查看TDE配置
SELECT name, setting FROM sys_settings WHERE name LIKE 'tde%';

-- 查看加密表空间
SELECT spcname, spcoptions FROM sys_tablespace WHERE spcoptions LIKE '%encryption%';

-- 查看加密表
SELECT relname, reloptions FROM sys_class WHERE reloptions LIKE '%encryption%';

2. 测试TDE加密效果

bash
# 尝试直接读取加密数据文件
hexdump -C /path/to/tde_tablespace/16384/12345 | head -20

# 比较加密和未加密数据文件的差异
ls -l /path/to/data/pg_tblspc/ /path/to/tde_tablespace/

3. 验证列级加密

sql
-- 查看加密列数据
SELECT phone_encrypted, id_card_encrypted FROM users;

-- 验证解密功能
SELECT 
  phone_encrypted,
  decrypt_data(phone_encrypted, 'master_key') as decrypted_phone,
  id_card_encrypted,
  decrypt_data(id_card_encrypted, 'master_key') as decrypted_id_card
FROM users;

数据加密性能优化

1. TDE性能优化

sql
-- 选择高效的加密算法
ALTER SYSTEM SET tde_cipher_algorithm = 'aes-256-cbc';

-- 配置加密缓存
ALTER SYSTEM SET tde_cache_size = '64MB';

-- 重启数据库使配置生效
-- sys_ctl restart -D /path/to/data

2. 列级加密性能优化

sql
-- 使用索引优化加密列查询
CREATE INDEX idx_users_phone_encrypted ON users (phone_encrypted);

-- 考虑使用哈希索引(如果适合)
CREATE INDEX idx_users_email ON users USING hash (email);

-- 优化加密函数
-- 考虑使用PL/SQL而不是SQL函数
-- 考虑使用缓存机制减少密钥查询

3. 硬件加速

如果服务器支持硬件加密加速,可以启用硬件加速功能:

bash
# 检查OpenSSL硬件加速支持
openssl engine -t

# 启用硬件加速
# 在openssl.cnf中配置
[openssl_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
CipherString = HIGH:!aNULL:!MD5:!3DES
MinProtocol = TLSv1.2
MaxProtocol = TLSv1.3
Engine = rdrand

版本差异

KingBaseES V8 R6

  • 支持基本的透明数据加密(TDE)
  • 支持列级加密
  • 支持AES-128, AES-256等加密算法
  • 密钥管理功能有限

KingBaseES V8 R7

  • 增强了透明数据加密功能
  • 支持更细粒度的加密控制
  • 提供了更丰富的加密算法支持
  • 增强了密钥管理功能
  • 支持密钥轮换
  • 提供了更详细的加密监控视图
sql
-- V8 R7新增:密钥轮换
ALTER SYSTEM SET tde_key_rotation_interval = '30 days';

-- V8 R7新增:加密状态监控
SELECT * FROM sys_tde_status;

-- V8 R7新增:密钥管理视图
SELECT * FROM sys_key_store;

常见问题(FAQ)

1. TDE加密会影响性能吗?

TDE加密会带来一定的性能开销,主要体现在:

  • 数据文件读写时的加密解密开销
  • 重做日志生成时的加密开销
  • 备份恢复时的加密解密开销

可以通过以下方式优化性能:

  • 选择高效的加密算法
  • 配置适当的加密缓存
  • 使用硬件加速
  • 只对敏感数据进行加密

2. 如何备份和恢复TDE密钥?

bash
# 备份TDE密钥
cp /opt/kingbase/tde/tde.key /path/to/backup/tde.key.$(date +%Y%m%d)

# 恢复TDE密钥
cp /path/to/backup/tde.key.20240101 /opt/kingbase/tde/tde.key
chmod 600 /opt/kingbase/tde/tde.key
chown kingbase:kingbase /opt/kingbase/tde/tde.key

3. 如何进行密钥轮换?

sql
-- 生成新的TDE密钥
openssl rand -hex 32 > /opt/kingbase/tde/tde.key.new
chmod 600 /opt/kingbase/tde/tde.key.new
chown kingbase:kingbase /opt/kingbase/tde/tde.key.new

-- 更新TDE密钥配置
ALTER SYSTEM SET tde_key_file = '/opt/kingbase/tde/tde.key.new';

-- 重启数据库使新密钥生效
-- sys_ctl restart -D /path/to/data

-- 执行密钥轮换(V8 R7+)
SELECT sys_rotate_tde_key();

4. 如何处理TDE密钥丢失?

如果TDE密钥丢失,将无法解密数据,因此需要:

  • 定期备份TDE密钥
  • 将密钥存储在安全的地方
  • 使用密钥管理系统(KMS)管理密钥
  • 建立密钥丢失应急处理流程

5. 列级加密如何处理索引?

列级加密的索引处理方式:

  • 可以在加密列上创建索引,但索引值也是加密的
  • 查询时需要先解密再比较,性能较低
  • 考虑使用哈希索引或部分索引
  • 考虑在应用层进行数据分片

6. 如何监控数据加密状态?

sql
-- 监控TDE状态(V8 R7+)
SELECT * FROM sys_tde_status;

-- 监控加密表空间
SELECT spcname, spcoptions FROM sys_tablespace WHERE spcoptions LIKE '%encryption%';

-- 监控加密表
SELECT relname, reloptions FROM sys_class WHERE reloptions LIKE '%encryption%';

-- 监控密钥使用情况
SELECT * FROM sys_key_store_usage;

数据加密最佳实践

1. 密钥管理

  • 使用强密钥,定期轮换
  • 安全存储密钥,权限设置为600
  • 使用密钥管理系统(KMS)管理密钥
  • 建立密钥备份和恢复机制
  • 限制密钥访问权限

2. 加密策略

  • 根据数据敏感度选择合适的加密方式
  • 对敏感数据进行分类,实施不同的加密策略
  • 考虑性能影响,避免过度加密
  • 定期审查加密策略

3. 访问控制

  • 实施最小权限原则
  • 限制对加密数据的访问
  • 使用行级安全策略(RLS)保护加密数据
  • 审计加密数据的访问

4. 备份和恢复

  • 确保备份包含加密密钥
  • 定期测试加密数据的恢复
  • 建立加密数据恢复流程
  • 考虑异地备份加密数据

5. 监控和审计

  • 监控加密状态和密钥使用情况
  • 审计加密数据的访问
  • 定期进行加密安全评估
  • 保持加密配置符合安全标准

数据加密安全审计脚本

1. TDE配置审计

sql
-- TDE配置审计报告
SELECT
    now() AS audit_time,
    (SELECT setting FROM sys_settings WHERE name = 'tde_enabled') AS tde_enabled,
    (SELECT setting FROM sys_settings WHERE name = 'tde_key_file') AS tde_key_file,
    (SELECT setting FROM sys_settings WHERE name = 'tde_cipher_algorithm') AS tde_algorithm,
    (SELECT setting FROM sys_settings WHERE name = 'tde_cache_size') AS tde_cache_size,
    (SELECT count(*) FROM sys_tablespace WHERE spcoptions LIKE '%encryption%') AS encrypted_tablespaces,
    (SELECT count(*) FROM sys_class WHERE reloptions LIKE '%encryption%') AS encrypted_tables
FROM
    sys_stat_activity
LIMIT 1;

2. 列级加密审计

sql
-- 列级加密审计报告
SELECT
    now() AS audit_time,
    (SELECT count(*) FROM sys_tables WHERE table_name LIKE '%encrypted%') AS encrypted_tables,
    (SELECT count(*) FROM sys_columns WHERE column_name LIKE '%encrypted%') AS encrypted_columns,
    (SELECT count(*) FROM sys_key_store) AS keys_in_store
FROM
    sys_stat_activity
LIMIT 1;

-- 查看加密列使用情况
SELECT
    table_name,
    column_name,
    data_type
FROM sys_columns
WHERE column_name LIKE '%encrypted%';

3. 密钥管理审计

bash
#!/bin/bash
# 数据加密密钥审计脚本

echo "=== KingBaseES Data Encryption Key Audit Report ==="
echo "Audit Time: $(date)"
echo "Hostname: $(hostname)"
echo ""

# 检查TDE密钥
TDE_KEY_FILE="/opt/kingbase/tde/tde.key"
echo "1. TDE Key:"
if [ -f "$TDE_KEY_FILE" ]; then
    echo "   File: $TDE_KEY_FILE"
    echo "   Permissions: $(stat -c "%a" "$TDE_KEY_FILE")"
    echo "   Owner: $(stat -c "%U:%G" "$TDE_KEY_FILE")"
    echo "   Size: $(stat -c "%s" "$TDE_KEY_FILE") bytes"
    echo "   Last Modified: $(stat -c "%y" "$TDE_KEY_FILE")"
else
    echo "   TDE key file not found!"
fi

echo ""

# 检查密钥备份
KEY_BACKUP_DIR="/path/to/backup"
echo "2. Key Backups:"
if [ -d "$KEY_BACKUP_DIR" ]; then
    echo "   Backup Directory: $KEY_BACKUP_DIR"
    echo "   Backup Files:"
    ls -la "$KEY_BACKUP_DIR"/tde.key.* 2>/dev/null || echo "   No backup files found!"
else
    echo "   Backup directory not found!"
fi

echo ""
echo "=== Audit Complete ==="

总结

数据加密是KingBaseES数据库安全的重要组成部分,通过合理配置透明数据加密(TDE)和列级加密,可以保护数据库静态数据的安全,防止数据泄露。在实际生产环境中,DBA应根据业务需求和安全策略,选择合适的数据加密方案,并定期进行监控和审计,确保数据加密的安全性和有效性。同时,结合访问控制、备份恢复和密钥管理等其他安全措施,可以构建更全面的数据库安全体系。