密钥与凭证管理

全面讲解企业级密钥管理方案:HashiCorp Vault 架构与使用、云厂商 KMS(AWS/Azure/GCP)、Kubernetes 外部密钥存储、动态凭证、密钥轮换与 HSM 硬件安全模块。

密钥、密码、API Key、证书等敏感凭证是攻击者的首要目标。硬编码在代码中的凭证是安全事件中最常见的入侵途径之一。本文系统讲解企业级密钥管理的方案选型与实践。


1. 为什么要专门的密钥管理

1.1 常见问题

❌ 密钥硬编码在代码中
   ├── Git 历史永久记录
   ├── 即使删除,commit 中仍可恢复
   └── 全团队可见

❌ 密钥存储在配置文件中
   ├── 配置文件权限管理困难
   ├── 多环境复用同一密钥
   └── 离职员工可能保留副本

❌ 密钥永不过期
   ├── 一旦泄露,永久有效
   └── 无法追踪谁在使用

1.2 理想密钥管理特性

特性说明
加密存储静态加密,密钥分片
访问控制基于身份的细粒度权限
审计日志谁、何时、访问了什么密钥
动态凭证短期、自动过期
自动轮换定期更换,无需停机
版本控制密钥版本管理和回滚
高可用集群部署,无单点故障

2. HashiCorp Vault

2.1 架构

┌─────────────────────────────────────────────────────────────┐
│                        Vault Cluster                         │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐   │
│  │ Vault Node  │    │ Vault Node  │    │ Vault Node  │   │
│  │  (Active)   │◄──►│ (Standby)   │◄──►│ (Standby)   │   │
│  │  Leader     │    │  (Raft)     │    │  (Raft)     │   │
│  └──────┬──────┘    └─────────────┘    └─────────────┘   │
│         │                                                    │
│         │  Storage Backend (Raft/Consul/...)                 │
│         └────────────────────────────────────────────►       │
│                                                              │
│  Unseal Keys (Shamir's Secret Sharing)                       │
│  - 5 把 key,需要 3 把才能 unseal                              │
└─────────────────────────────────────────────────────────────┘

2.2 核心概念

概念说明
Secrets Engine存储/生成 Secrets 的插件(KV、Database、PKI、AWS…)
Auth Method认证方式(Token/K8s/AppRole/LDAP/GitHub/OIDC…)
Policies基于路径的 ACL
Token访问 Vault 的凭证,可设置 TTL 和权限

2.3 KV Secrets Engine

# 启用 KV v2(版本化)
vault secrets enable -path=secret -version=2 kv

# 写入密钥
vault kv put secret/app/database \
  username=dbuser \
  password=supersecret

# 读取密钥
vault kv get -format=json secret/app/database

# 版本管理
vault kv put secret/app/database password=newpass  # 创建 v2
vault kv get -version=1 secret/app/database        # 读取 v1
vault kv delete secret/app/database                # 软删除
vault kv undelete -versions=2 secret/app/database  # 恢复
vault kv destroy -versions=2 secret/app/database   # 永久删除

2.4 动态数据库凭证

# 启用数据库引擎
vault secrets enable database

# 配置 PostgreSQL 连接
vault write database/config/my-postgresql \
  plugin_name=postgresql-database-plugin \
  allowed_roles="app" \
  connection_url="postgresql://{{username}}:{{password}}@db:5432/mydb" \
  username="vaultadmin" \
  password="vaultpass"

# 创建角色(定义生成的凭证权限)
vault write database/roles/app \
  db_name=my-postgresql \
  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
  default_ttl=1h \
  max_ttl=24h

# 获取动态凭证
vault read database/creds/app
# 返回:username=v-token-app-xxx, password=xxx, lease_duration=3600

# 应用使用 1 小时后,凭证自动过期,Vault 自动清理数据库用户

2.5 Kubernetes 集成

# Vault + K8s 认证 + External Secrets Operator
apiVersion: v1
kind: ServiceAccount
metadata:
  name: vault-auth
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: vault-auth-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
- kind: ServiceAccount
  name: vault-auth
  namespace: default
---
# External Secret 从 Vault 同步到 K8s Secret
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: vault-db-secret
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: SecretStore
    name: vault-backend
  target:
    name: db-credentials
  data:
    - secretKey: password
      remoteRef:
        key: secret/data/app/database
        property: password

3. 云厂商密钥管理服务

3.1 AWS KMS + Secrets Manager

import boto3

# KMS 加密/解密
kms = boto3.client('kms')

# 加密
encrypted = kms.encrypt(
    KeyId='alias/my-key',
    Plaintext=b'my-secret'
)

# Secrets Manager
secrets = boto3.client('secretsmanager')

# 创建密钥
secrets.create_secret(
    Name='prod/myapp/database',
    SecretString='{"username":"admin","password":"xxx"}'
)

# 获取密钥(自动解密)
response = secrets.get_secret(SecretId='prod/myapp/database')
credentials = json.loads(response['SecretString'])

# 自动轮换
secrets.rotate_secret(
    SecretId='prod/myapp/database',
    RotationLambdaARN='arn:aws:lambda:...:rotation-function'
)

3.2 阿里云 KMS

// 阿里云 KMS SDK
Config config = new Config()
    .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
    .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
    .setEndpoint("kms.cn-hangzhou.aliyuncs.com");

Client client = new Client(config);

// 解密数据密钥
DecryptRequest decryptReq = new DecryptRequest()
    .setCiphertextBlob(cipherKey);
DecryptResponse decryptRsp = client.decrypt(decryptReq);
byte[] plainKey = Base64.decode(decryptRsp.getBody().getPlaintext());

4. 动态凭证与短期凭证

4.1 为什么需要动态凭证

静态凭证问题:
- 泄露后长期有效
- 无法追踪谁在使用
- 轮换需要所有应用同时更新

动态凭证优势:
- 短期有效(TTL)
- 每个客户端获得唯一凭证
- 泄露影响范围和时间窗口有限
- 使用记录可审计

4.2 实现模式

服务动态凭证实现
数据库Vault Database Secret Engine
AWSVault AWS Secret Engine / IAM Role Chaining
SSHVault SSH Secret Engine(Signed SSH Certificates)
PKI / TLSVault PKI Secret Engine(短期证书)

4.3 Vault PKI 短期证书

# 启用 PKI
vault secrets enable pki
vault secrets tune -max-lease-ttl=8760h pki

# 生成根证书
vault write -field=certificate pki/root/generate/internal \
  common_name="example.com" \
  ttl=8760h > ca.crt

# 创建角色(签发服务器证书)
vault write pki/roles/web-server \
  allowed_domains=example.com \
  allow_subdomains=true \
  max_ttl=72h

# 客户端获取短期证书
vault write -format=json pki/issue/web-server \
  common_name=app.example.com \
  ttl=24h
# 返回:certificate, issuing_ca, private_key, ca_chain

5. HSM(硬件安全模块)

5.1 为什么需要 HSM

软件密钥存储风险:
- 内存中密钥可被 dump
- 进程调试可提取密钥
- 管理员可直接读取

HSM 优势:
- 密钥永不离开硬件
- 加密运算在硬件中进行
- 防篡改(物理破坏即销毁密钥)
- FIPS 140-2 Level 3 认证

5.2 主流 HSM

产品类型适用
AWS CloudHSM云托管AWS 环境
Azure Dedicated HSM云托管Azure 环境
Thales Luna 7硬件/云企业级
Entrust nShield硬件金融/政府
HashiCorp Vault + HSM混合自动 unseal

5.3 Vault + HSM Auto-unseal

# vault.hcl
seal "pkcs11" {
  lib = "/usr/lib/softhsm/libsofthsm2.so"
  slot = "0"
  pin = "1234"
  key_label = "vault-unseal-key"
  hmac_key_label = "vault-hmac-key"
  generate_key = "true"
}

6. 密钥轮换策略

密钥轮换策略:

手动轮换:
1. 生成新密钥
2. 更新所有使用方
3. 验证
4. 删除旧密钥
(风险:窗口期长,容易遗漏)

自动轮换(推荐):
1. 定期自动生成新密钥
2. 双密钥并行期(新旧同时有效)
3. 所有方自动获取新密钥
4. 旧密钥优雅退役

6.1 Vault 自动轮换

# 启用自动轮换
vault write database/rotate-role/app \
  db_name=my-postgresql

# 手动触发轮换
vault write -f database/rotate-root/my-postgresql

# K8s External Secrets 自动同步
# 配置 refreshInterval,定期从 Vault 拉取最新密钥

7. 密钥管理 Checklist

检查项建议
无硬编码密钥使用环境变量或密钥管理服务
密钥加密存储静态加密,密钥分片
短期凭证优先使用 Vault/AWS IAM 动态生成
定期轮换自动化,最小中断
访问审计谁访问了什么密钥
最小权限每个服务只访问所需密钥
紧急情况密钥撤销/轮换预案

8. 总结

密钥管理的核心原则:

┌─────────────────────────────────────────────────────────┐
│                     密钥管理层次                         │
├─────────────────────────────────────────────────────────┤
│  最外层: 动态凭证(推荐)                                 │
│     - Vault Database / AWS IAM / GCP Service Account      │
│     - 短期、唯一、自动过期                                 │
│                                                         │
│  中间层: 集中式密钥管理                                    │
│     - HashiCorp Vault / AWS Secrets Manager / Azure KeyVault│
│     - 加密存储、访问控制、审计                             │
│                                                         │
│  核心层: HSM(最高安全)                                   │
│     - CloudHSM / Luna / nShield                           │
│     - FIPS 140-2, 密钥不出硬件                            │
└─────────────────────────────────────────────────────────┘

好的密钥管理应该让开发者感受不到密钥的存在——自动注入、自动轮换、自动过期。任何需要手动复制粘贴密钥的场景都是安全隐患。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「安全」更多文章

  1. Kubernetes安全体系:RBAC、PodSecurity与NetworkPolicy实战
  2. 安全合规与数据保护
  3. 渗透测试与红蓝对抗