← 返回首页
🔒

密钥管理架构:Vault与Secrets

📂 architecture ⏱ 3 min 479 words

密钥管理架构:Vault与Secrets

HashiCorp Vault集成

Vault是企业级的密钥管理解决方案,提供安全的密钥存储、动态密钥生成和访问控制。

// Vault客户端配置
@Configuration
public class VaultConfig {
    
    @Bean
    public VaultTemplate vaultTemplate() {
        VaultConfig config = VaultConfig.builder()
            .address("https://vault.example.com")
            .token(System.getenv("VAULT_TOKEN"))
            .build();
        
        return new VaultTemplate(config);
    }
}

// Vault服务
@Service
public class VaultSecretService {
    
    private final VaultTemplate vault;
    
    // 获取密钥
    public String getSecret(String path) {
        VaultResponse response = vault.read(path);
        
        if (response == null) {
            throw new SecretNotFoundException("密钥不存在: " + path);
        }
        
        return (String) response.getData().get("value");
    }
    
    // 获取KV v2密钥
    public Map<String, Object> getKVSecret(String path, String version) {
        String fullPath = path + "?version=" + version;
        KVv2KeyValueOperations operations = vault.opsForKv().keyValueOperations();
        
        return operations.get(fullPath);
    }
    
    // 存储密钥
    public void putSecret(String path, String value) {
        Map<String, Object> data = Map.of("value", value);
        vault.write(path, data);
    }
    
    // 动态数据库密钥
    public DatabaseCredentials getDynamicDBCredentials() {
        VaultResponse response = vault.read("database/creds/my-role");
        
        return DatabaseCredentials.builder()
            .username((String) response.getData().get("username"))
            .password((String) response.getData().get("password"))
            .leaseId(response.getLeaseId())
            .build();
    }
    
    // 动态AWS密钥
    public AWSCredentials getDynamicAWSCredentials() {
        VaultResponse response = vault.read("aws/creds/my-role");
        
        Map<String, Object> data = response.getData();
        
        return AWSCredentials.builder()
            .accessKey((String) data.get("access_key"))
            .secretKey((String) data.get("secret_key"))
            .securityToken((String) data.get("security_token"))
            .build();
    }
}

Kubernetes Sealed Secrets

// Sealed Secrets管理
@Component
public class SealedSecretManager {
    
    private final KubernetesClient kubernetesClient;
    private final SealedSecretsCrypto crypto;
    
    // 加密封钥
    public SealedSecret sealSecret(Secret secret, String sealedSecretName) {
        // 序列化原始Secret
        String secretYaml = serializeSecret(secret);
        
        // 使用公钥加密
        byte[] encryptedData = crypto.encrypt(
            secretYaml.getBytes(),
            getPublicKey()
        );
        
        // 创建SealedSecret
        SealedSecret sealedSecret = new SealedSecretBuilder()
            .withNewMetadata()
                .withName(sealedSecretName)
                .withNamespace(secret.getMetadata().getNamespace())
            .endMetadata()
            .withNewSpec()
                .addNewEncryptedData()
                    .withKey("secret-key")
                    .withValue(Base64.getEncoder().encodeToString(encryptedData))
                .endEncryptedData()
            .endSpec()
            .build();
        
        return sealedSecret;
    }
    
    // 解密封钥
    public Secret unsealSecret(SealedSecret sealedSecret) {
        // 获取加密数据
        String encryptedValue = sealedSecret.getSpec()
            .getEncryptedData()
            .get("secret-key");
        
        byte[] encryptedData = Base64.getDecoder().decode(encryptedValue);
        
        // 使用私钥解密
        byte[] decryptedData = crypto.decrypt(
            encryptedData,
            getPrivateKey()
        );
        
        // 反序列化为Secret
        return deserializeSecret(new String(decryptedData));
    }
    
    // 自动同步
    @Scheduled(fixedRate = 300000) // 5分钟
    public void syncSealedSecrets() {
        List<SealedSecret> sealedSecrets = kubernetesClient
            .resources(SealedSecret.class)
            .list()
            .getItems();
        
        for (SealedSecret sealed : sealedSecrets) {
            try {
                Secret secret = unsealSecret(sealed);
                applySecret(secret);
            } catch (Exception e) {
                log.error("同步SealedSecret失败: {}", sealed.getMetadata().getName(), e);
            }
        }
    }
}

密钥轮换策略

// 密钥轮换服务
@Service
public class KeyRotationService {
    
    private final KeyStore keyStore;
    private final AuditLogger auditLogger;
    
    // 定期轮换密钥
    @Scheduled(cron = "0 0 2 1 * ?") // 每月1日凌晨2点
    public void rotateEncryptionKeys() {
        log.info("开始密钥轮换...");
        
        // 1. 生成新密钥
        SecretKey newKey = generateNewKey();
        
        // 2. 获取当前密钥
        SecretKey currentKey = keyStore.getCurrentKey();
        
        // 3. 使用新密钥重新加密数据
        reencryptData(currentKey, newKey);
        
        // 4. 切换到新密钥
        keyStore.rotateKey(newKey);
        
        // 5. 归档旧密钥
        keyStore.archiveKey(currentKey);
        
        // 6. 记录审计日志
        auditLogger.logKeyRotation(currentKey.getId(), newKey.getId());
        
        log.info("密钥轮换完成");
    }
    
    // 紧急密钥撤销
    public void emergencyRevokeKey(String keyId) {
        log.warn("紧急撤销密钥: {}", keyId);
        
        // 1. 立即撤销密钥
        keyStore.revokeKey(keyId);
        
        // 2. 使所有使用该密钥的令牌失效
        invalidateAllTokensForKey(keyId);
        
        // 3. 触发重新认证
        forceReauthentication();
        
        // 4. 发送安全警报
        alertService.sendSecurityAlert(
            "紧急密钥撤销",
            "密钥 " + keyId + " 已被紧急撤销,所有相关访问已被终止"
        );
        
        // 5. 记录审计日志
        auditLogger.logEmergencyKeyRevocation(keyId);
    }
}

安全存储最佳实践

# 密钥管理配置
secrets_management:
  vault:
    enabled: true
    address: "https://vault.example.com"
    auth_method: "kubernetes"
    role: "my-app"
    mount_path: "secret"
    
    secrets:
      - name: "database"
        path: "secret/data/database"
        rotation_days: 90
      
      - name: "api_keys"
        path: "secret/data/api-keys"
        rotation_days: 30
      
      - name: "certificates"
        path: "secret/data/certs"
        rotation_days: 365
  
  sealed_secrets:
    enabled: true
    controller_namespace: "kube-system"
    
    auto_rotation:
      enabled: true
      interval_days: 90
  
  encryption:
    algorithm: "AES-256-GCM"
    key_derivation: "PBKDF2"
    
    at_rest:
      enabled: true
      key_vault: "azure-keyvault"
    
    in_transit:
      enabled: true
      tls_version: "1.3"
  
  audit:
    enabled: true
    log_path: "/var/log/secrets-audit.log"
    events:
      - read
      - write
      - delete
      - rotate
      - revoke

密钥管理架构通过Vault、Sealed Secrets和完善的轮换策略,确保密钥的安全存储和生命周期管理。