← 返回首页
🧠

API密钥管理

📂 llm ⏱ 3 min 444 words

--- title: "API密钥管理" description: "全面介绍LLM API密钥的生成、存储、轮换和安全管理实践" tags: ["API密钥", "密钥管理", "安全"] category: "llm" icon: "🧠"

API密钥管理

为什么密钥管理很重要

API密钥是访问LLM服务的凭证,一旦泄露可能导致账户被盗用、产生巨额费用或数据泄露。有效的密钥管理策略是保护LLM应用安全的基础。

密钥生成最佳实践

使用安全的随机数生成器

import secrets
import hashlib
from datetime import datetime

class APIKeyGenerator:
    def __init__(self, prefix="sk"):
        self.prefix = prefix
    
    def generate_key(self, length=48) -> str:
        # 使用密码学安全的随机数生成器
        random_bytes = secrets.token_bytes(length)
        key_material = secrets.token_hex(length // 2)
        
        return f"{self.prefix}-{key_material}"
    
    def generate_scoped_key(self, scopes: list, user_id: str) -> str:
        key = self.generate_key()
        
        # 将作用域信息编码到密钥中(不包含敏感信息)
        scope_hash = hashlib.sha256(
            f"{user_id}:{':'.join(scopes)}".encode()
        ).hexdigest()[:8]
        
        return f"{key}_{scope_hash}"

密钥格式规范

建议采用清晰的密钥格式,便于识别和管理。

class APIKeyFormat:
    # 常见的密钥格式示例
    FORMATS = {
        "openai": "sk-[48个字符]",
        "anthropic": "sk-ant-[32个字符]",
        "custom": "llm_[环境]_[40个字符]"
    }
    
    @staticmethod
    def validate_format(api_key: str, format_type: str) -> bool:
        import re
        
        patterns = {
            "openai": r"^sk-[a-zA-Z0-9]{48}$",
            "anthropic": r"^sk-ant-[a-zA-Z0-9]{32}$",
            "custom": r"^llm_(prod|dev|test)_[a-zA-Z0-9]{40}$"
        }
        
        pattern = patterns.get(format_type)
        if not pattern:
            return False
        
        return bool(re.match(pattern, api_key))

安全存储方案

环境变量

最简单但有效的存储方式。

import os
from dataclasses import dataclass

@dataclass
class LLMConfig:
    api_key: str
    org_id: str = None
    base_url: str = None
    
    @classmethod
    def from_env(cls) -> "LLMConfig":
        api_key = os.getenv("LLM_API_KEY")
        if not api_key:
            raise ValueError("LLM_API_KEY环境变量未设置")
        
        return cls(
            api_key=api_key,
            org_id=os.getenv("LLM_ORG_ID"),
            base_url=os.getenv("LLM_BASE_URL")
        )

密钥管理服务

企业环境应使用专业的密钥管理服务。

import hvac  # HashiCorp Vault客户端

class VaultKeyManager:
    def __init__(self, vault_url, token):
        self.client = hvac.Client(url=vault_url, token=token)
    
    def get_secret(self, path: str, key: str) -> str:
        secret = self.client.secrets.kv.v2.read_secret_version(
            path=path
        )
        return secret["data"]["data"][key]
    
    def rotate_secret(self, path: str, key: str, new_value: str):
        self.client.secrets.kv.v2.create_or_update_secret(
            path=path,
            secret={key: new_value}
        )
    
    def list_secrets(self, path: str) -> list:
        return self.client.secrets.kv.v2.list_secrets_versions(
            path=path
        )

密钥轮换策略

定期轮换

设置自动轮换周期,降低密钥泄露风险。

from datetime import datetime, timedelta
from typing import Optional

class KeyRotationManager:
    def __init__(self, rotation_days: int = 90):
        self.rotation_days = rotation_days
        self.key_registry = {}
    
    def register_key(self, key_id: str, created_at: datetime):
        self.key_registry[key_id] = {
            "created_at": created_at,
            "last_rotated": created_at,
            "is_active": True
        }
    
    def needs_rotation(self, key_id: str) -> bool:
        if key_id not in self.key_registry:
            return True
        
        key_info = self.key_registry[key_id]
        days_since_rotation = (datetime.now() - key_info["last_rotated"]).days
        
        return days_since_rotation >= self.rotation_days
    
    def rotate_key(self, key_id: str, new_key_func) -> str:
        if key_id not in self.key_registry:
            raise ValueError(f"密钥 {key_id} 不存在")
        
        new_key = new_key_func()
        
        # 保留旧密钥一段时间用于验证
        self.key_registry[key_id]["is_active"] = False
        self.key_registry[f"{key_id}_backup"] = {
            "key": self.key_registry[key_id].get("key"),
            "expires_at": datetime.now() + timedelta(hours=24)
        }
        
        # 注册新密钥
        self.key_registry[key_id] = {
            "key": new_key,
            "created_at": datetime.now(),
            "last_rotated": datetime.now(),
            "is_active": True
        }
        
        return new_key

密钥使用监控

监控密钥使用情况,及时发现异常。

from collections import defaultdict
from datetime import datetime, timedelta

class KeyUsageMonitor:
    def __init__(self):
        self.usage_records = defaultdict(list)
        self.alerts = []
    
    def record_usage(self, key_id: str, endpoint: str, 
                     success: bool, response_time: float):
        self.usage_records[key_id].append({
            "timestamp": datetime.now(),
            "endpoint": endpoint,
            "success": success,
            "response_time": response_time
        })
    
    def detect_anomalies(self, key_id: str) -> list:
        anomalies = []
        records = self.usage_records.get(key_id, [])
        
        if len(records) < 10:
            return anomalies
        
        # 检查请求频率异常
        recent_records = [r for r in records 
                         if r["timestamp"] > datetime.now() - timedelta(hours=1)]
        
        if len(recent_records) > 1000:
            anomalies.append({
                "type": "high_frequency",
                "message": f"过去1小时内有{len(recent_records)}次请求",
                "severity": "high"
            })
        
        # 检查失败率异常
        failure_count = sum(1 for r in recent_records if not r["success"])
        failure_rate = failure_count / len(recent_records) if recent_records else 0
        
        if failure_rate > 0.5:
            anomalies.append({
                "type": "high_failure_rate",
                "message": f"失败率{failure_rate:.2%}超过阈值",
                "severity": "medium"
            })
        
        return anomalies

安全检查清单

  1. 不在代码中硬编码密钥:使用环境变量或密钥管理服务
  2. 限制密钥作用域:只授予必要的最小权限
  3. 启用密钥轮换:定期更换密钥
  4. 监控使用情况:设置异常告警
  5. 及时撤销泄露密钥:发现泄露立即禁用
  6. 使用不同的密钥:生产、测试环境使用不同密钥

正确的密钥管理能有效降低安全风险,保护你的LLM应用。