3、数据加密与密钥管理:传输层加密(TLS)、存储加密(AES/RSA)、密钥生命周期管理、HSM与KMS

数据加密这事儿,说白了就是给数据穿上防弹衣。传输中要穿,存储时也要穿。我见过太多SaaS系统,只给传输加了密,数据库里却明文存着用户密码——这就像把家门锁得死死的,但保险柜却敞着门。

今天咱们就把加密这件事聊透。从传输到存储,从算法到密钥管理,一步不落。

3.1 传输层加密:TLS 不只是个证书

很多人觉得TLS就是买个证书装上完事。嗯,这里要注意——配置不当的TLS,比不加密还危险。

我个人习惯,在Nginx或网关层强制使用TLS 1.2以上版本。TLS 1.0和1.1已经被攻破多次,别再用了。

# Nginx 配置示例
server {
    listen 443 ssl;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_certificate /etc/ssl/certs/yourdomain.crt;
    ssl_certificate_key /etc/ssl/private/yourdomain.key;
}

我在项目中遇到过一件事:某客户把所有API都暴露在公网上,但只对前端页面做了TLS。结果攻击者直接抓包分析API请求,拿到了用户token。后来我们强制所有API端点也走HTTPS,才堵住这个洞。

避坑指南: 我曾经见过一个团队,证书过期了三个月都没发现。用户访问时浏览器直接报安全警告,导致大量用户流失。建议用自动化工具监控证书有效期,提前30天告警。

3.2 存储加密:AES 和 RSA 各司其职

存储加密分两种:对称加密和非对称加密。你想想看,AES就像一把钥匙开一把锁,速度快;RSA就像一把公钥加密、私钥解密,适合小数据量。

AES-256-GCM 是我最推荐的对称加密模式。它自带认证标签,能防止数据被篡改。

// Java 示例:AES-256-GCM 加密
import javax.crypto.*;
import javax.crypto.spec.*;

public class AESUtil {
    private static final int GCM_IV_LENGTH = 12;
    private static final int GCM_TAG_LENGTH = 16;

    public static byte[] encrypt(byte[] plaintext, SecretKey key) throws Exception {
        byte[] iv = new byte[GCM_IV_LENGTH];
        SecureRandom.getInstanceStrong().nextBytes(iv);
        
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, spec);
        
        byte[] ciphertext = cipher.doFinal(plaintext);
        // 将 IV 和密文拼接存储
        return ByteBuffer.allocate(iv.length + ciphertext.length)
                .put(iv).put(ciphertext).array();
    }
}

RSA 适合做什么? 它不适合加密大文件,但非常适合加密AES密钥。这就是混合加密的思路:用RSA保护AES密钥,用AES加密实际数据。

核心原则: 永远不要用RSA加密超过密钥长度的数据。RSA-2048一次最多加密245字节。超过这个长度,请用AES。

3.3 密钥生命周期管理

密钥不能一直用。就像密码要定期换一样,密钥也有生命周期。我建议按以下阶段管理:

  1. 生成:使用安全的随机数生成器,比如Java的SecureRandom或Linux的/dev/urandom
  2. 分发:通过安全通道传输,比如用KMS API或HSM内部传输
  3. 使用:限制使用次数和用途,比如一个密钥只用于加密,不用于签名
  4. 轮换:定期更换密钥,建议90-180天轮换一次
  5. 归档:旧密钥保留一段时间,用于解密历史数据
  6. 销毁:彻底删除,确保无法恢复

为什么会这样?因为密钥用得越久,被泄露的风险越大。我在项目中遇到过,一个团队用了同一把密钥加密了三年数据。后来密钥泄露,所有历史数据都得重新加密——那叫一个痛苦。

我的习惯: 每次轮换密钥时,给新密钥加一个版本号。比如key_v1、key_v2。这样解密时可以根据版本号找到对应的密钥,不影响历史数据读取。

3.4 HSM 与 KMS:硬件级 vs 软件级

HSM(硬件安全模块)和KMS(密钥管理服务)是密钥管理的两种主流方案。说白了,HSM是物理设备,KMS是云服务。

特性 HSM KMS
安全性 极高(物理隔离) 高(软件隔离)
性能 高(专用硬件) 中等(共享资源)
成本 高(数万到数十万) 低(按量付费)
适用场景 金融、政府、高合规要求 大多数SaaS应用
管理复杂度 高(需专业人员) 低(云厂商托管)

我个人建议:如果你的SaaS系统需要合规认证(比如PCI DSS、SOC 2),至少用KMS。如果涉及金融交易或国家级数据,上HSM。

我曾经帮一个金融科技公司选型。他们一开始想省钱,用自建数据库加密。结果审计时被指出密钥和密文存在同一台服务器上——这等于把钥匙挂在门上。后来我们上了AWS KMS,密钥和密文分离存储,审计才通过。

避坑指南: 我曾经见过一个团队,把KMS的主密钥权限开给了所有开发人员。结果有人误删了密钥,导致所有加密数据无法解密。记住:最小权限原则——只有运维和安全管理团队才能操作主密钥。

3.5 实战建议:加密策略落地

说了这么多,落地才是关键。我总结了几条实战建议:

  • 传输加密:全站HTTPS,HSTS头设置至少一年,证书用自动化工具管理
  • 存储加密:敏感字段(密码、身份证、银行卡)用AES-256-GCM加密,密钥用KMS管理
  • 密钥轮换:设置自动化轮换策略,每季度轮换一次
  • 审计日志:记录所有密钥操作,包括谁、什么时间、做了什么
  • 备份恢复:定期测试密钥恢复流程,确保灾难发生时能恢复数据

你想想看,如果有一天你的数据库被拖库了,但所有敏感字段都是加密的——攻击者拿到一堆乱码,那才是真正的安全。

加密不是万能的,但不加密是万万不能的。希望今天的分享能帮你把数据安全这件事,做得更扎实。