配置加解密使用指南

本指南说明如何使用加解密器保护配置文件中的敏感信息。

为什么需要配置加解密?

配置文件中可能包含敏感信息(如数据库密码、API Key 等),直接明文存储存在安全风险。使用配置加解密功能,可以将敏感信息加密后再保存到配置文件中。

快速开始

步骤1:设置加密秘钥

在应用启动代码中设置加密秘钥:

# app.py
from olc.encryptor import OlcEncryptorRegistry

# 方式A:直接设置加密秘钥(开发环境)
OlcEncryptorRegistry.create_aes("your_secret_key")

# 方式B:从环境变量读取(生产环境推荐)
OlcEncryptorRegistry.create_aes_from_env("OLC_ENCRYPTOR_PASSWORD")

步骤2:加密敏感信息

创建一个工具脚本来加密你的敏感信息:

# tools/encrypt_config.py
from olc.encryptor import OlcEncryptorRegistry

# 设置加密秘钥(与应用中使用的一致)
OlcEncryptorRegistry.create_aes("your_secret_key")
encryptor = OlcEncryptorRegistry.get()

# 需要加密的敏感信息
values = {
    "olc.redis.passwd": "redis_password_123",
    "olc.other.secret": "my_secret_key"
}

#得到加密后的敏感信息
for key, value in values.items():
    encrypted = encryptor.encrypt(value)
    print(f"{key}=ENC({encrypted})")

运行脚本:

python tools/encrypt_config.py 

得到加密后的敏感信息

步骤3:更新配置文件

将加密后的输出的敏感信息 复制到你的配置文件中:

# overload-config.properties
olc.sdk.domain=my-service
olc.redis.passwd=ENC(Gq3XR1VBMCYCDdWhh...)
olc.other.secret=ENC(abc123def456...)

步骤4:正常使用配置

配置管理器会自动解密这些值,你无需做其他改动:

from olc.config.properties_loader import OlcConfigManager

config_manager = OlcConfigManager.get_instance()

# 获取的配置已是明文
redis_password = config_manager.get_redis_config().passwd
print(redis_password)  # 输出:redis_password_123

详细使用

由上面步骤1到步骤4得到加密后的敏感信息后,怎么在olc使用呢?请看以下详解

第一步:设置秘钥

设置秘钥有多种方式,以下详解每种方式怎么使用:

  • 方式1:使用秘钥器创建(olc提供对应接口),最简单的方式,直接传入秘钥:
from olc.encryptor import OlcEncryptorRegistry

OlcEncryptorRegistry.create_aes("your_secret_key")
  • 方式2:从环境变量读取,更安全的方式,秘钥不存储在代码中:
from olc.encryptor import OlcEncryptorRegistry

# 从 OLC_ENCRYPTOR_PASSWORD 环境变量读取
OlcEncryptorRegistry.create_aes_from_env("OLC_ENCRYPTOR_PASSWORD")

设置环境变量:

# Linux/Mac
export OLC_ENCRYPTOR_PASSWORD=your_secret_key

# Windows
set OLC_ENCRYPTOR_PASSWORD=your_secret_key

也可以设置默认秘钥(当环境变量不存在时使用):

OlcEncryptorRegistry.create_aes_from_env(
    "OLC_ENCRYPTOR_PASSWORD",
    default_password="your_secret_key"
)
  • 方式3:直接设置秘钥实例,如果你需要更多控制:
from olc.encryptor import OlcEncryptorRegistry, AesEncryptor

encryptor = AesEncryptor("your_secret_key")
OlcEncryptorRegistry.set(encryptor)

秘钥优先级

配置管理器按以下优先级选择秘钥:

  1. 显式传入的秘钥器

    encryptor = AesEncryptor("your_secret_key")
    manager = OlcConfigManager.get_instance(encryptor=encryptor)
    
  2. OlcEncryptorRegistry 中设置的秘钥器

    OlcEncryptorRegistry.create_aes("your_secret_key")
    manager = OlcConfigManager.get_instance()
    
  3. 不使用加密器(加密值保持原样)

自定义加解密器

你可以实现自定义的加密算法:

from olc.encryptor import Encryptor, OlcEncryptorRegistry

class MyCustomEncryptor(Encryptor):
    def encrypt(self, raw: str) -> str:
        # 实现你的加密逻辑
        return your_encrypted_value

    def decrypt(self, raw: str) -> str:
        # 实现你的解密逻辑
        return your_decrypted_value

# 设置自定义加密器
OlcEncryptorRegistry.set(MyCustomEncryptor())

完整示例

在 FastAPI 应用中使用

import os
from fastapi import FastAPI
from olc.adapters.fastapi import OlcFastAPIAdapter
from olc.encryptor import OlcEncryptorRegistry
from olc.config.properties_loader import OlcConfigManager

app = FastAPI()

# 1. 在应用启动时设置秘钥
OlcEncryptorRegistry.create_aes_from_env(
    "OLC_ENCRYPTOR_PASSWORD",
    default_password="dev_password"
)

# 2. 设置配置文件路径
config_dir = os.path.join(os.path.dirname(__file__), "config")
os.environ["OLC_CONFIG_PATH"] = config_dir

# 3. 添加 OLC 中间件
app.add_middleware(OlcFastAPIAdapter)


@app.post("/api/chat")
async def chat():
    # 获取配置(已自动解密)
    config_manager = OlcConfigManager.get_instance()
    redis_config = config_manager.get_redis_config()
    print(redis_config.passwd)  # 明文密码
    
    return {"message": "Hello!"}

加密配置工具

创建一个便捷的工具来加密配置:

#!/usr/bin/env python3
import sys
from olc.encryptor import OlcEncryptorRegistry, AesEncryptor

def encrypt_value(password: str, value: str) -> str:
    encryptor = AesEncryptor(password)
    return encryptor.encrypt(value)

def decrypt_value(password: str, value: str) -> str:
    encryptor = AesEncryptor(password)
    return encryptor.decrypt(value)

if __name__ == "__main__":
    if len(sys.argv) < 4:
        print("Usage:")
        print("  Encrypt: python encrypt_tool.py encrypt <password> <value>")
        print("  Decrypt: python encrypt_tool.py decrypt <password> <value>")
        sys.exit(1)
    
    cmd = sys.argv[1]
    password = sys.argv[2]
    value = sys.argv[3]
    
    if cmd == "encrypt":
        print(f"ENC({encrypt_value(password, value)})")
    elif cmd == "decrypt":
        # 去掉 ENC(...) 包装
        if value.startswith("ENC(") and value.endswith(")"):
            value = value[4:-1]
        print(decrypt_value(password, value))
    else:
        print(f"Unknown command: {cmd}")

使用方式:

# 加密
python encrypt_tool.py encrypt my_password "redis_secret_123"
# 输出: ENC(...)

# 解密
python encrypt_tool.py decrypt my_password "ENC(abc123...)"
# 输出: redis_secret_123

安全最佳实践

  1. 使用环境变量

    • 生产环境务必使用环境变量存储密码
    • 不要将密码提交到代码仓库
  2. 密码强度

    • 使用强密码(至少16字符,包含大小写、数字、特殊字符)
    • 定期更换密码
  3. 环境隔离

    • 不同环境使用不同的加密密码
    • 开发、测试、生产环境密码分开管理
  4. 加密值范围

    • 只加密真正敏感的配置项
    • 不需要加密的配置保持明文,方便调试

常见问题

Q: 忘记加密密码怎么办?

A: 无法恢复,需要重新生成加密值并更新配置文件。

Q: 可以更换加密算法吗?

A: 可以,实现 Encryptor 接口即可自定义算法。

Q: 加密后的配置值太长怎么办?

A: AES加密后会有固定的 overhead,但通常配置值都不长,这是正常的。

Q: 热更新配置时加密值会自动解密吗?

A: 是的,只要加密器已设置,热更新也会自动解密。

相关链接