Skip to content

PostgreSQL 加密规范

传输加密(SSL/TLS)

SSL/TLS 配置

  1. 生成证书

    bash
    # 创建证书目录
    mkdir -p /path/to/ssl
    cd /path/to/ssl
    
    # 生成CA私钥
    openssl genrsa -des3 -out ca.key 2048
    
    # 生成CA证书
    openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
    
    # 生成服务器私钥
    openssl genrsa -des3 -out server.key 2048
    
    # 生成证书签名请求
    openssl req -new -key server.key -out server.csr
    
    # 生成服务器证书
    openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
    
    # 移除私钥密码
    openssl rsa -in server.key -out server.key
    
    # 设置权限
    chmod 600 server.key
    chown postgres:postgres server.key server.crt ca.crt
  2. 配置postgresql.conf

    sql
    -- 启用SSL
    ALTER SYSTEM SET ssl = 'on';
    
    -- 配置证书路径
    ALTER SYSTEM SET ssl_cert_file = '/path/to/ssl/server.crt';
    ALTER SYSTEM SET ssl_key_file = '/path/to/ssl/server.key';
    ALTER SYSTEM SET ssl_ca_file = '/path/to/ssl/ca.crt';
    
    -- 配置SSL协议版本
    ALTER SYSTEM SET ssl_min_protocol_version = 'TLSv1.2';
    ALTER SYSTEM SET ssl_max_protocol_version = 'TLSv1.3';
  3. 配置pg_hba.conf

    # 要求所有连接使用SSL
    hostssl    all             all             0.0.0.0/0               scram-sha-256
    hostssl    all             all             ::1/128                 scram-sha-256
    
    # 可选:允许特定IP使用非SSL连接
    host       all             all             192.168.1.0/24          scram-sha-256

SSL 验证级别

  1. 客户端验证配置

    sql
    -- 配置客户端证书验证
    ALTER SYSTEM SET ssl_prefer_server_ciphers = 'on';
    ALTER SYSTEM SET ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL';
  2. SSL 验证级别

    • verify-ca:验证服务器CA证书
    • verify-full:验证服务器CA证书和主机名
    • 客户端连接示例:
      bash
      psql "host=server_host dbname=dbname user=username sslmode=verify-full sslrootcert=/path/to/ca.crt"

数据加密(存储加密)

透明数据加密 (TDE) 替代方案

  1. 文件系统加密

    • 使用 LUKS (Linux) 或 BitLocker (Windows) 加密数据目录
    • 示例(LUKS):
      bash
      # 创建加密卷
      cryptsetup luksFormat /dev/sdb1
      cryptsetup open /dev/sdb1 pg_data
      mkfs.ext4 /dev/mapper/pg_data
      mount /dev/mapper/pg_data /path/to/pg_data
  2. 表空间加密

    sql
    -- 创建加密表空间
    -- 注意:PostgreSQL 本身不支持表空间加密,需要结合文件系统加密
    CREATE TABLESPACE encrypted_ts LOCATION '/path/to/encrypted/directory';
    
    -- 创建表时使用加密表空间
    CREATE TABLE encrypted_table (id INT, data TEXT) TABLESPACE encrypted_ts;

列级加密

  1. pgcrypto 扩展

    sql
    -- 安装pgcrypto扩展
    CREATE EXTENSION IF NOT EXISTS pgcrypto;
    
    -- 创建加密表
    CREATE TABLE sensitive_data (
        id SERIAL PRIMARY KEY,
        name TEXT NOT NULL,
        credit_card BYTEA NOT NULL,
        ssn BYTEA NOT NULL
    );
    
    -- 插入加密数据
    INSERT INTO sensitive_data (name, credit_card, ssn) 
    VALUES (
        'John Doe',
        pgp_sym_encrypt('1234-5678-9012-3456', 'encryption_key'),
        pgp_sym_encrypt('123-45-6789', 'encryption_key')
    );
    
    -- 查询加密数据
    SELECT 
        name,
        pgp_sym_decrypt(credit_card, 'encryption_key') AS credit_card,
        pgp_sym_decrypt(ssn, 'encryption_key') AS ssn
    FROM sensitive_data;
  2. 哈希函数

    sql
    -- 使用哈希函数存储密码
    CREATE TABLE users (
        id SERIAL PRIMARY KEY,
        username TEXT UNIQUE NOT NULL,
        password_hash TEXT NOT NULL
    );
    
    -- 插入哈希密码
    INSERT INTO users (username, password_hash) 
    VALUES ('user1', crypt('password123', gen_salt('bf')));
    
    -- 验证密码
    SELECT * FROM users WHERE username = 'user1' AND password_hash = crypt('password123', password_hash);

密码加密

密码存储配置

  1. 密码加密算法

    sql
    -- 使用scram-sha-256加密算法
    ALTER SYSTEM SET password_encryption = 'scram-sha-256';
    
    -- 验证配置
    SHOW password_encryption;
  2. 密码复杂度要求

    sql
    -- 安装passwordcheck扩展(PostgreSQL 14+)
    CREATE EXTENSION IF NOT EXISTS passwordcheck;
    
    -- 配置密码复杂度(通过修改passwordcheck.c源码并重新编译)
    -- 或使用第三方扩展如pgcrypto的密码验证

连接密码加密

  1. 连接字符串加密
    • 使用 .pgpass 文件存储密码
    • 配置示例:
      # ~/.pgpass 文件内容
      hostname:port:database:username:password
      *:*:*:user1:password123
    • 设置权限:
      bash
      chmod 600 ~/.pgpass

加密扩展

pgcrypto 扩展

  1. 功能特性

    • 对称加密:AES, 3DES, Blowfish
    • 非对称加密:RSA
    • 哈希函数:MD5, SHA-1, SHA-256, SHA-512
    • 随机数生成
  2. 使用示例

    sql
    -- 生成随机数
    SELECT gen_random_bytes(16);
    
    -- 计算哈希值
    SELECT md5('test');
    SELECT sha256('test');
    
    -- 非对称加密
    SELECT pgp_pub_encrypt('secret message', dearmor('-----BEGIN PGP PUBLIC KEY BLOCK-----...'));

sslinfo 扩展

  1. 功能特性

    • 提供SSL连接信息
    • 检查客户端证书
  2. 使用示例

    sql
    -- 安装sslinfo扩展
    CREATE EXTENSION IF NOT EXISTS sslinfo;
    
    -- 查看SSL连接信息
    SELECT ssl_is_used(), ssl_version(), ssl_cipher();

加密性能优化

性能影响因素

  1. 加密算法选择

    • AES-256-GCM:安全性高,性能好
    • 避免使用低效率算法如3DES
  2. 硬件加速

    • 确保CPU支持AES-NI指令集
    • 验证硬件加速是否启用:
      sql
      SELECT name, setting FROM pg_settings WHERE name LIKE '%ssl%' OR name LIKE '%crypto%';
  3. 配置优化

    sql
    -- 优化SSL性能
    ALTER SYSTEM SET ssl_prefer_server_ciphers = 'on';
    ALTER SYSTEM SET ssl_ciphers = 'HIGH:!aNULL:!MD5:!3DES';
    ALTER SYSTEM SET ssl_ecdh_curve = 'prime256v1';

监控与审计

加密状态监控

  1. 检查SSL连接

    sql
    -- 查看当前连接是否使用SSL
    SELECT usename, application_name, client_addr, ssl, ssl_version, ssl_cipher 
    FROM pg_stat_activity WHERE ssl = true;
  2. 审计加密配置变更

    sql
    -- 配置日志记录加密相关配置变更
    ALTER SYSTEM SET log_statement = 'ddl';
    ALTER SYSTEM SET log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h ';

最佳实践

传输加密最佳实践

  1. 强制使用SSL

    • 在生产环境中强制所有连接使用SSL
    • 配置pg_hba.conf只允许hostssl连接
  2. 定期更新证书

    • 证书有效期建议不超过365天
    • 建立证书轮换机制
  3. 使用强密码套件

    • 优先使用TLSv1.2或TLSv1.3
    • 避免使用不安全的密码套件

数据加密最佳实践

  1. 分层加密策略

    • 传输层:SSL/TLS
    • 存储层:文件系统加密
    • 应用层:列级加密
  2. 密钥管理

    • 使用专用密钥管理系统(如HashiCorp Vault)
    • 避免硬编码密钥
    • 定期轮换密钥
  3. 最小权限原则

    • 只有授权用户才能访问加密数据
    • 限制pgcrypto扩展的使用权限

密码加密最佳实践

  1. 使用强密码算法

    • 优先使用scram-sha-256
    • 避免使用md5(仅用于兼容旧版本)
  2. 定期更换密码

    • 配置密码有效期
    • 强制用户定期更换密码
  3. 多因素认证

    • 结合外部认证系统实现多因素认证
    • 如使用PgAuth或集成LDAP+MFA

常见问题(FAQ)

Q1:如何检查PostgreSQL是否启用了SSL?

A1:

sql
-- 检查SSL配置
SHOW ssl;

-- 查看SSL证书文件
SHOW ssl_cert_file;
SHOW ssl_key_file;
SHOW ssl_ca_file;

-- 检查当前连接是否使用SSL
SELECT ssl_is_used();

Q2:SSL加密会影响性能吗?

A2:

  • SSL加密会带来一定的性能开销(通常5-15%)
  • 使用硬件加速(AES-NI)可以显著降低性能影响
  • 优化SSL配置可以减少性能开销
  • 建议在生产环境中启用SSL,安全性收益远大于性能损失

Q3:如何实现PostgreSQL的透明数据加密(TDE)?

A3: PostgreSQL本身不直接支持TDE,但可以通过以下方式实现:

  1. 使用文件系统加密(LUKS、BitLocker)
  2. 使用存储级加密(如AWS EBS加密)
  3. 使用第三方解决方案(如pg_tde扩展)
  4. 使用加密表空间(结合文件系统加密)

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

A4:

  1. 使用专用密钥管理系统(KMS)
  2. 如HashiCorp Vault、AWS KMS、Azure Key Vault
  3. 避免将密钥存储在数据库服务器上
  4. 实现密钥轮换机制
  5. 限制密钥访问权限

Q5:如何验证客户端证书?

A5:

  1. 在pg_hba.conf中使用cert认证方式
  2. 配置示例:
    hostssl    all             all             0.0.0.0/0               cert clientcert=1
  3. 客户端需要提供有效的证书
  4. 服务器验证客户端证书的有效性和信任链