| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- """
- 大模型部署 API Key 生成器
- 特性:
- - 生成加密安全的随机 API Key
- - 支持多种格式(UUID、随机字符串、JWT 风格)
- - 包含前缀标识(便于区分用途和环境)
- - 支持校验和验证(防止篡改)
- - 可配置 Key 长度和复杂度
- 使用示例:
- # 生成标准 API Key
- key = generate_api_key(prefix="sk-prod")
- # 生成带有项目标识的 Key
- key = generate_api_key(prefix="sk-dev", project_id="proj_123")
- # 验证 API Key 格式
- is_valid = validate_api_key(key, prefix="sk-prod")
- """
- import secrets
- import hashlib
- import base64
- import re
- import json
- import hmac
- from datetime import datetime, timedelta
- from typing import Optional, Tuple, Dict, Any
- from dataclasses import dataclass
- from enum import Enum
- class KeyFormat(Enum):
- """API Key 格式类型"""
- STANDARD = "standard" # 标准格式: prefix_xxxxxxxxx
- UUID = "uuid" # UUID 格式
- JWT_STYLE = "jwt_style" # JWT 风格: xxxxx.yyyyy.zzzzz
- BASE64 = "base64" # Base64 编码
- HEX = "hex" # 十六进制
- @dataclass
- class APIKeyConfig:
- """API Key 配置"""
- prefix: str = "sk" # 前缀,如 sk, pk, dk(secret key, public key, dev key)
- environment: str = "prod" # 环境:prod, dev, test
- length: int = 32 # 随机部分长度
- include_checksum: bool = True # 是否包含校验和
- include_timestamp: bool = False # 是否包含时间戳
- project_id: Optional[str] = None # 项目标识
- secret_key: Optional[str] = None # 用于签名(HMAC)
- class APIKeyGenerator:
- """API Key 生成器"""
- # 推荐的密钥长度(字节)
- RECOMMENDED_LENGTHS = {
- "low": 16, # 128 bit
- "medium": 24, # 192 bit
- "high": 32, # 256 bit
- "maximum": 48 # 384 bit
- }
- def __init__(self, config: Optional[APIKeyConfig] = None):
- self.config = config or APIKeyConfig()
- def generate(self, format_type: KeyFormat = KeyFormat.STANDARD) -> str:
- """
- 生成 API Key
- Args:
- format_type: Key 格式类型
- Returns:
- str: 生成的 API Key
- """
- generators = {
- KeyFormat.STANDARD: self._generate_standard,
- KeyFormat.UUID: self._generate_uuid,
- KeyFormat.JWT_STYLE: self._generate_jwt_style,
- KeyFormat.BASE64: self._generate_base64,
- KeyFormat.HEX: self._generate_hex,
- }
- generator = generators.get(format_type, self._generate_standard)
- return generator()
- def _generate_standard(self) -> str:
- """生成标准格式 API Key: prefix_env_xxxxxxxxx_checksum"""
- # 构建前缀
- prefix_parts = [self.config.prefix]
- if self.config.environment:
- prefix_parts.append(self.config.environment)
- if self.config.project_id:
- prefix_parts.append(self.config.project_id)
- prefix = "_".join(prefix_parts)
- # 生成随机部分
- random_bytes = secrets.token_bytes(self.config.length)
- random_part = base64.urlsafe_b64encode(random_bytes).decode('ascii').rstrip('=')
- # 可选:添加时间戳
- if self.config.include_timestamp:
- timestamp = hex(int(datetime.utcnow().timestamp()))[2:]
- random_part = f"{timestamp}_{random_part[:24]}"
- # 构建基础 key
- base_key = f"{prefix}_{random_part[:self.config.length]}"
- # 可选:添加校验和
- if self.config.include_checksum:
- checksum = self._calculate_checksum(base_key)
- return f"{base_key}_{checksum}"
- return base_key
- def _generate_uuid(self) -> str:
- """生成 UUID 风格 API Key"""
- # 生成 16 字节随机数
- random_bytes = secrets.token_bytes(16)
- # 转换为 UUID 格式
- hex_str = random_bytes.hex()
- uuid_format = f"{hex_str[:8]}-{hex_str[8:12]}-{hex_str[12:16]}-{hex_str[16:20]}-{hex_str[20:32]}"
- prefix = f"{self.config.prefix}-{self.config.environment}" if self.config.environment else self.config.prefix
- return f"{prefix}-{uuid_format}"
- def _generate_jwt_style(self) -> str:
- """生成 JWT 风格 API Key: header.payload.signature"""
- # Header
- header = {
- "alg": "HS256" if self.config.secret_key else "none",
- "typ": "API-KEY",
- "env": self.config.environment,
- "prefix": self.config.prefix
- }
- header_b64 = base64.urlsafe_b64encode(
- json.dumps(header, separators=(',', ':')).encode()
- ).decode().rstrip('=')
- # Payload(随机数据 + 时间戳)
- payload_data = secrets.token_hex(16)
- payload = {
- "rnd": payload_data,
- "iat": int(datetime.utcnow().timestamp()),
- "project": self.config.project_id or "default"
- }
- payload_b64 = base64.urlsafe_b64encode(
- json.dumps(payload, separators=(',', ':')).encode()
- ).decode().rstrip('=')
- # Signature
- if self.config.secret_key:
- message = f"{header_b64}.{payload_b64}"
- signature = hmac.new(
- self.config.secret_key.encode(),
- message.encode(),
- hashlib.sha256
- ).digest()
- signature_b64 = base64.urlsafe_b64encode(signature).decode().rstrip('=')[:16]
- else:
- signature_b64 = secrets.token_urlsafe(16).rstrip('=')
- return f"{header_b64}.{payload_b64}.{signature_b64}"
- def _generate_base64(self) -> str:
- """生成 Base64 编码 API Key"""
- random_bytes = secrets.token_bytes(self.config.length)
- encoded = base64.urlsafe_b64encode(random_bytes).decode('ascii').rstrip('=')
- prefix = f"{self.config.prefix}_{self.config.environment}_" if self.config.environment else f"{self.config.prefix}_"
- return f"{prefix}{encoded}"
- def _generate_hex(self) -> str:
- """生成十六进制 API Key"""
- random_bytes = secrets.token_bytes(self.config.length)
- hex_str = random_bytes.hex()
- prefix = f"{self.config.prefix}_{self.config.environment}_" if self.config.environment else f"{self.prefix}_"
- return f"{prefix}{hex_str}"
- def _calculate_checksum(self, data: str) -> str:
- """计算校验和(前 8 位)"""
- hash_obj = hashlib.sha256(data.encode())
- return hash_obj.hexdigest()[:8]
- @staticmethod
- def validate(api_key: str, prefix: Optional[str] = None,
- secret_key: Optional[str] = None) -> Tuple[bool, Optional[Dict[str, Any]]]:
- """
- 验证 API Key 格式
- Args:
- api_key: 要验证的 API Key
- prefix: 期望的前缀(可选)
- secret_key: 用于验证签名的密钥(可选)
- Returns:
- Tuple[bool, Optional[Dict]]: (是否有效, 解析后的信息)
- """
- if not api_key or len(api_key) < 16:
- return False, None
- info = {"raw": api_key}
- # 检查前缀
- if prefix and not api_key.startswith(prefix):
- return False, info
- # 尝试解析 JWT 风格
- if '.' in api_key and api_key.count('.') == 2:
- return APIKeyGenerator._validate_jwt_style(api_key, secret_key, info)
- # 尝试解析标准格式(检查校验和)
- if '_' in api_key:
- return APIKeyGenerator._validate_standard(api_key, info)
- return True, info
- @staticmethod
- def _validate_jwt_style(api_key: str, secret_key: Optional[str],
- info: Dict) -> Tuple[bool, Dict]:
- """验证 JWT 风格 Key"""
- parts = api_key.split('.')
- if len(parts) != 3:
- return False, info
- try:
- # 解码 header
- header_padding = '=' * (4 - len(parts[0]) % 4)
- header_json = base64.urlsafe_b64decode(parts[0] + header_padding)
- header = json.loads(header_json)
- info["header"] = header
- # 解码 payload
- payload_padding = '=' * (4 - len(parts[1]) % 4)
- payload_json = base64.urlsafe_b64decode(parts[1] + payload_padding)
- payload = json.loads(payload_json)
- info["payload"] = payload
- # 验证签名(如果提供了 secret_key)
- if secret_key and header.get("alg") == "HS256":
- message = f"{parts[0]}.{parts[1]}"
- expected_sig = hmac.new(
- secret_key.encode(),
- message.encode(),
- hashlib.sha256
- ).digest()
- expected_sig_b64 = base64.urlsafe_b64encode(expected_sig).decode().rstrip('=')[:16]
- if not hmac.compare_digest(parts[2], expected_sig_b64):
- return False, info
- return True, info
- except Exception:
- return False, info
- @staticmethod
- def _validate_standard(api_key: str, info: Dict) -> Tuple[bool, Dict]:
- """验证标准格式 Key(带校验和)"""
- parts = api_key.split('_')
- # 如果有校验和部分(最后一部分是 8 位十六进制)
- if len(parts) >= 2 and len(parts[-1]) == 8 and all(c in '0123456789abcdef' for c in parts[-1]):
- # 提取基础 key 和校验和
- checksum = parts[-1]
- base_key = '_'.join(parts[:-1])
- # 验证校验和
- expected_checksum = hashlib.sha256(base_key.encode()).hexdigest()[:8]
- if checksum != expected_checksum:
- return False, info
- info["checksum_valid"] = True
- info["parts"] = parts[:-1] # 排除校验和部分
- else:
- info["parts"] = parts
- return True, info
- # ========== 便捷函数 ==========
- def generate_api_key(
- prefix: str = "sk",
- environment: str = "prod",
- length: int = 32,
- format_type: KeyFormat = KeyFormat.STANDARD,
- include_checksum: bool = True,
- project_id: Optional[str] = None,
- secret_key: Optional[str] = None
- ) -> str:
- """
- 便捷函数:生成 API Key
- Args:
- prefix: 前缀(如 sk, pk, dk)
- environment: 环境(prod, dev, test)
- length: 随机部分长度
- format_type: 格式类型
- include_checksum: 是否包含校验和
- project_id: 项目标识
- secret_key: 用于签名的密钥
- Returns:
- str: 生成的 API Key
- Examples:
- >>> generate_api_key()
- 'sk_prod_xxxxxxxxxxxxxxxx_xxxxxxxx'
- >>> generate_api_key(prefix="sk-dev", environment="test")
- 'sk-dev_test_xxxxxxxxxxxxxxxx_xxxxxxxx'
- >>> generate_api_key(format_type=KeyFormat.UUID)
- 'sk-prod-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
- """
- config = APIKeyConfig(
- prefix=prefix,
- environment=environment,
- length=length,
- include_checksum=include_checksum,
- project_id=project_id,
- secret_key=secret_key
- )
- generator = APIKeyGenerator(config)
- return generator.generate(format_type)
- def validate_api_key(
- api_key: str,
- prefix: Optional[str] = None,
- secret_key: Optional[str] = None
- ) -> bool:
- """
- 便捷函数:验证 API Key 格式
- Args:
- api_key: 要验证的 Key
- prefix: 期望的前缀(可选)
- secret_key: 用于验证签名的密钥(可选)
- Returns:
- bool: 是否有效
- """
- is_valid, _ = APIKeyGenerator.validate(api_key, prefix, secret_key)
- return is_valid
- def parse_api_key(api_key: str) -> Optional[Dict[str, Any]]:
- """
- 解析 API Key,提取其中的信息
- Args:
- api_key: API Key
- Returns:
- Optional[Dict]: 解析出的信息,无效返回 None
- """
- is_valid, info = APIKeyGenerator.validate(api_key)
- return info if is_valid else None
- # ========== 批量生成工具 ==========
- def generate_api_keys_batch(
- count: int = 10,
- prefix: str = "sk",
- environment: str = "prod",
- format_type: KeyFormat = KeyFormat.STANDARD,
- save_to_file: Optional[str] = None
- ) -> list:
- """
- 批量生成 API Key
- Args:
- count: 生成数量
- prefix: 前缀
- environment: 环境
- format_type: 格式
- save_to_file: 保存到文件路径(可选)
- Returns:
- list: API Key 列表
- """
- config = APIKeyConfig(prefix=prefix, environment=environment)
- generator = APIKeyGenerator(config)
- keys = [generator.generate(format_type) for _ in range(count)]
- if save_to_file:
- with open(save_to_file, 'w', encoding='utf-8') as f:
- f.write("# Generated API Keys\n")
- f.write(f"# Count: {count}\n")
- f.write(f"# Format: {format_type.value}\n")
- f.write(f"# Environment: {environment}\n")
- f.write("-" * 50 + "\n")
- for i, key in enumerate(keys, 1):
- f.write(f"{i}. {key}\n")
- print(f"Keys saved to: {save_to_file}")
- return keys
- # ========== 主程序 ==========
- if __name__ == "__main__":
- print("=" * 60)
- print("大模型部署 API Key 生成器")
- print("=" * 60)
- # 演示各种格式的 API Key
- formats = [
- ("标准格式", KeyFormat.STANDARD),
- ("UUID 格式", KeyFormat.UUID),
- ("JWT 风格", KeyFormat.JWT_STYLE),
- ("Base64 格式", KeyFormat.BASE64),
- ("十六进制格式", KeyFormat.HEX),
- ]
- print("\n1. 不同格式的 API Key 示例:")
- print("-" * 60)
- for name, fmt in formats:
- key = generate_api_key(format_type=fmt)
- print(f"\n{name}:")
- print(f" {key}")
- # 不同环境的 Key
- print("\n\n2. 不同环境的 API Key:")
- print("-" * 60)
- for env in ["prod", "dev", "test"]:
- key = generate_api_key(environment=env)
- print(f"\n{env.upper()}:")
- print(f" {key}")
- # 带校验和的 Key
- print("\n\n3. 带校验和的 Key(可验证完整性):")
- print("-" * 60)
- key_with_checksum = generate_api_key(include_checksum=True)
- print(f"\n生成: {key_with_checksum}")
- is_valid = validate_api_key(key_with_checksum)
- print(f"验证: {'✓ 有效' if is_valid else '✗ 无效'}")
- # 验证被篡改的 Key
- tampered_key = key_with_checksum[:-8] + "12345678"
- print(f"\n篡改: {tampered_key}")
- is_valid = validate_api_key(tampered_key)
- print(f"验证: {'✓ 有效' if is_valid else '✗ 无效(校验和不匹配)'}")
- # 带项目标识的 Key
- print("\n\n4. 带项目标识的 Key:")
- print("-" * 60)
- key_with_project = generate_api_key(
- prefix="sk",
- environment="prod",
- project_id="proj_chatbot"
- )
- print(f"\n{key_with_project}")
- # 批量生成
- print("\n\n5. 批量生成(10 个测试 Key):")
- print("-" * 60)
- test_keys = generate_api_keys_batch(
- count=5,
- prefix="sk-test",
- environment="dev",
- format_type=KeyFormat.STANDARD
- )
- for i, key in enumerate(test_keys, 1):
- print(f" {i}. {key}")
- # 带签名的 JWT 风格 Key
- print("\n\n6. 带 HMAC 签名的 JWT 风格 Key:")
- print("-" * 60)
- secret = "your-secret-key-here-keep-it-safe"
- jwt_key = generate_api_key(
- format_type=KeyFormat.JWT_STYLE,
- secret_key=secret,
- environment="prod",
- project_id="llm-api"
- )
- print(f"\n生成: {jwt_key}")
- # 验证签名
- is_valid, info = APIKeyGenerator.validate(jwt_key, secret_key=secret)
- print(f"签名验证: {'✓ 有效' if is_valid else '✗ 无效'}")
- if info and "payload" in info:
- print(f"解析信息:")
- for k, v in info["payload"].items():
- print(f" {k}: {v}")
- print("\n" + "=" * 60)
- print("使用说明:")
- print("=" * 60)
- print("""
- 建议的生产环境使用方式:
- 1. 生成高安全级别的 Key:
- key = generate_api_key(
- prefix="sk",
- environment="prod",
- length=32,
- include_checksum=True
- )
- 2. 使用带项目标识的 Key 便于管理:
- key = generate_api_key(
- prefix="sk",
- project_id="your_project_id"
- )
- 3. 使用 HMAC 签名防止篡改:
- key = generate_api_key(
- format_type=KeyFormat.JWT_STYLE,
- secret_key=your_secret_key
- )
- 4. 批量生成并保存到文件:
- keys = generate_api_keys_batch(
- count=100,
- save_to_file="api_keys.txt"
- )
- 安全建议:
- - 在生产环境使用 32 字节(256 bit)以上的密钥长度
- - 妥善保管 secret_key,不要硬编码在代码中
- - 定期轮换 API Key
- - 使用环境变量或密钥管理系统存储敏感信息
- """)
|