Python脚本如何加密存储缓存敏感数据

wen python案例 30

本文目录导读:

Python脚本如何加密存储缓存敏感数据

  1. 使用Fernet对称加密(推荐)
  2. 使用密钥管理服务
  3. 使用环境变量 + 加密
  4. 使用HSM或云密钥管理服务
  5. 内存安全缓存
  6. 最佳实践建议

对于Python脚本中敏感数据的加密存储,推荐以下几种安全方案:

使用Fernet对称加密(推荐)

from cryptography.fernet import Fernet
import base64
import os
class SecureCache:
    def __init__(self, key=None):
        # 如果没有提供密钥,生成新密钥
        if key is None:
            key = Fernet.generate_key()
        self.key = key
        self.cipher = Fernet(key)
    def encrypt_data(self, data: bytes) -> bytes:
        """加密数据"""
        return self.cipher.encrypt(data)
    def decrypt_data(self, encrypted_data: bytes) -> bytes:
        """解密数据"""
        return self.cipher.decrypt(encrypted_data)
    def save_encrypted(self, filepath: str, data: bytes):
        """保存加密数据到文件"""
        encrypted = self.encrypt_data(data)
        with open(filepath, 'wb') as f:
            f.write(encrypted)
    def load_encrypted(self, filepath: str) -> bytes:
        """从文件加载加密数据"""
        with open(filepath, 'rb') as f:
            encrypted = f.read()
        return self.decrypt_data(encrypted)
# 使用示例
cache = SecureCache()
# 加密敏感数据
sensitive_data = b"password123"
encrypted = cache.encrypt_data(sensitive_data)
# 解密
decrypted = cache.decrypt_data(encrypted)

使用密钥管理服务

import os
import json
from cryptography.fernet import Fernet
from keyring import get_password, set_password
class SecureKeyManager:
    """安全密钥管理器"""
    def __init__(self, service_name="myapp"):
        self.service_name = service_name
        self._load_or_create_key()
    def _load_or_create_key(self):
        """从系统密钥环加载或创建密钥"""
        stored_key = get_password(self.service_name, "encryption_key")
        if stored_key:
            self.key = stored_key.encode()
        else:
            self.key = Fernet.generate_key()
            set_password(self.service_name, "encryption_key", self.key.decode())
        self.cipher = Fernet(self.key)
    def encrypt(self, data: str) -> str:
        return self.cipher.encrypt(data.encode()).decode()
    def decrypt(self, encrypted_data: str) -> str:
        return self.cipher.decrypt(encrypted_data.encode()).decode()
# 使用系统密钥环安全存储
key_manager = SecureKeyManager()
encrypted = key_manager.encrypt("api_key_12345")
decrypted = key_manager.decrypt(encrypted)

使用环境变量 + 加密

import os
import base64
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
class EnvironmentSecureCache:
    def __init__(self, password_env_var="CACHE_PASSWORD"):
        # 从环境变量获取密码
        password = os.environ.get(password_env_var)
        if not password:
            raise ValueError(f"环境变量 {password_env_var} 未设置")
        # 使用PBKDF2派生密钥
        salt = b'fixed_salt_16_bytes'  # 实际应用中应该随机生成并存储
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(),
            length=32,
            salt=salt,
            iterations=100000,
        )
        key = base64.urlsafe_b64encode(kdf.derive(password.encode()))
        self.cipher = Fernet(key)
    def encrypt(self, data):
        return self.cipher.encrypt(data.encode() if isinstance(data, str) else data)
    def decrypt(self, encrypted_data):
        return self.cipher.decrypt(encrypted_data).decode()
# 设置环境变量(生产环境应通过安全方式设置)
# os.environ["CACHE_PASSWORD"] = "your_strong_password"

使用HSM或云密钥管理服务

import boto3
from botocore.exceptions import ClientError
import base64
class AWSKMSEncryption:
    """使用AWS KMS进行加密"""
    def __init__(self, key_id):
        self.kms = boto3.client('kms')
        self.key_id = key_id
    def encrypt(self, data: str) -> bytes:
        response = self.kms.encrypt(
            KeyId=self.key_id,
            Plaintext=data.encode()
        )
        return response['CiphertextBlob']
    def decrypt(self, encrypted_data: bytes) -> str:
        response = self.kms.decrypt(
            CiphertextBlob=encrypted_data
        )
        return response['Plaintext'].decode()
# 使用示例
# kms = AWSKMSEncryption('your-kms-key-id')
# encrypted = kms.encrypt("敏感数据")
# decrypted = kms.decrypt(encrypted)

内存安全缓存

import hashlib
import hmac
import os
from typing import Optional, Dict
class MemorySecureCache:
    """内存中的安全缓存"""
    def __init__(self, master_key: bytes):
        self.master_key = master_key
        self.cache: Dict[str, bytes] = {}
    def _derive_key(self, cache_key: str) -> bytes:
        """为每个缓存项派生唯一密钥"""
        return hmac.new(
            self.master_key,
            cache_key.encode(),
            hashlib.sha256
        ).digest()[:32]
    def store(self, key: str, value: str):
        """安全存储数据"""
        encrypt_key = self._derive_key(key)
        from cryptography.fernet import Fernet
        import base64
        cipher = Fernet(base64.urlsafe_b64encode(encrypt_key))
        self.cache[key] = cipher.encrypt(value.encode())
    def retrieve(self, key: str) -> Optional[str]:
        """安全检索数据"""
        if key not in self.cache:
            return None
        encrypt_key = self._derive_key(key)
        from cryptography.fernet import Fernet
        import base64
        cipher = Fernet(base64.urlsafe_b64encode(encrypt_key))
        return cipher.decrypt(self.cache[key]).decode()
    def clear(self):
        """清除所有缓存"""
        self.cache.clear()
# 使用示例
master_key = os.urandom(32)
secure_cache = MemorySecureCache(master_key)
secure_cache.store("api_key", "sk-1234567890")
api_key = secure_cache.retrieve("api_key")

最佳实践建议

  1. 密钥管理

    • 永远不要在代码中硬编码密钥
    • 使用环境变量、密钥管理服务或硬件安全模块
    • 定期轮换密钥
  2. 数据分类

    • 只在必要时缓存敏感数据
    • 设置合理的过期时间
    • 实施访问控制
  3. 安全配置

    class SecureConfig:
        # 从安全源加载配置
        @staticmethod
        def load_config():
            config = {
                'encryption_key': os.environ.get('ENCRYPTION_KEY'),
                'cache_ttl': 3600,  # 1小时
                'max_cache_size': 100 * 1024 * 1024,  # 100MB
            }
            return config
  4. 日志和审计

    • 记录访问尝试
    • 监控异常行为
    • 实施告警机制

选择合适的方案取决于你的安全需求、基础设施和预算,对于大多数应用,使用Fernet对称加密配合密钥管理服务是最佳选择。

抱歉,评论功能暂时关闭!