Python脚本如何校验缓存数据完整性

wen python案例 31

本文目录导读:

Python脚本如何校验缓存数据完整性

  1. 使用哈希校验
  2. CRC校验
  3. 完整缓存管理类
  4. 数据库级别完整性
  5. 最佳实践建议

我来介绍几种在Python中校验缓存数据完整性的常见方法:

使用哈希校验

基础实现

import hashlib
import json
import pickle
from typing import Any, Dict, Optional
class CacheWithHash:
    def __init__(self, cache_dir: str = "cache"):
        self.cache_dir = cache_dir
        self.cache = {}
    def _calculate_hash(self, data: Any) -> str:
        """计算数据的哈希值"""
        # 序列化数据
        serialized = pickle.dumps(data)
        # 计算SHA256哈希
        return hashlib.sha256(serialized).hexdigest()
    def store_with_hash(self, key: str, data: Any, metadata: Optional[Dict] = None):
        """存储数据及其哈希值"""
        cache_entry = {
            'data': data,
            'hash': self._calculate_hash(data),
            'metadata': metadata or {}
        }
        self.cache[key] = cache_entry
        return True
    def verify_and_retrieve(self, key: str) -> Optional[Any]:
        """验证并获取数据"""
        if key not in self.cache:
            return None
        cache_entry = self.cache[key]
        current_hash = self._calculate_hash(cache_entry['data'])
        if current_hash != cache_entry['hash']:
            # 数据完整性被破坏
            print(f"警告: 缓存数据 '{key}' 的完整性被破坏")
            del self.cache[key]
            return None
        return cache_entry['data']

使用HMAC增加安全性

import hmac
import hashlib
import secrets
class SecureCacheWithHMAC:
    def __init__(self, secret_key: Optional[bytes] = None):
        self.cache = {}
        # 使用安全的随机密钥
        self.secret_key = secret_key or secrets.token_bytes(32)
    def _calculate_hmac(self, data: bytes) -> str:
        """计算HMAC"""
        h = hmac.new(self.secret_key, data, hashlib.sha256)
        return h.hexdigest()
    def store(self, key: str, data: bytes):
        """安全存储数据"""
        hmac_value = self._calculate_hmac(data)
        self.cache[key] = {
            'data': data,
            'hmac': hmac_value
        }
    def retrieve(self, key: str) -> Optional[bytes]:
        """验证并获取数据"""
        cache_entry = self.cache.get(key)
        if not cache_entry:
            return None
        expected_hmac = self._calculate_hmac(cache_entry['data'])
        if not hmac.compare_digest(expected_hmac, cache_entry['hmac']):
            raise ValueError(f"数据完整性验证失败: {key}")
        return cache_entry['data']

CRC校验

import zlib
from typing import Any, Optional
class CacheWithCRC:
    def __init__(self):
        self.cache = {}
    def store(self, key: str, data: Any):
        """存储数据及其CRC校验值"""
        serialized = str(data).encode('utf-8')
        crc_value = zlib.crc32(serialized)
        self.cache[key] = {
            'data': data,
            'crc32': crc_value
        }
    def verify(self, key: str) -> bool:
        """验证数据完整性"""
        if key not in self.cache:
            return False
        cache_entry = self.cache[key]
        serialized = str(cache_entry['data']).encode('utf-8')
        current_crc = zlib.crc32(serialized)
        return current_crc == cache_entry['crc32']

完整缓存管理类

import hashlib
import json
import time
from typing import Any, Dict, Optional, Union
from pathlib import Path
class IntegratedCacheManager:
    """集成多种校验方法的缓存管理器"""
    def __init__(self, cache_file: str = "cache.json", 
                 use_checksum: bool = True,
                 use_version: bool = True):
        self.cache_file = Path(cache_file)
        self.cache: Dict[str, Dict] = {}
        self.use_checksum = use_checksum
        self.use_version = use_version
        self.version = "1.0"
        # 加载现有缓存
        self._load_cache()
    def _load_cache(self):
        """从文件加载缓存"""
        if self.cache_file.exists():
            try:
                with open(self.cache_file, 'r') as f:
                    loaded_cache = json.load(f)
                    # 验证缓存文件完整性
                    if self._verify_cache_integrity(loaded_cache):
                        self.cache = loaded_cache
                    else:
                        print("缓存文件完整性验证失败,使用空缓存")
                        self.cache = {}
            except (json.JSONDecodeError, IOError) as e:
                print(f"加载缓存失败: {e}")
                self.cache = {}
    def _verify_cache_integrity(self, cache: Dict) -> bool:
        """验证整个缓存的完整性"""
        if not self.use_checksum:
            return True
        for key, entry in cache.items():
            if 'checksum' in entry:
                expected_checksum = entry['checksum']
                # 移除checksum后计算
                entry_without_checksum = {**entry}
                del entry_without_checksum['checksum']
                calculated = self._calculate_checksum(entry_without_checksum)
                if calculated != expected_checksum:
                    return False
        return True
    def _calculate_checksum(self, data: Dict) -> str:
        """计算校验和"""
        serialized = json.dumps(data, sort_keys=True).encode('utf-8')
        return hashlib.md5(serialized).hexdigest()
    def store(self, key: str, value: Any, 
              expiry: Optional[int] = None,
              metadata: Optional[Dict] = None) -> bool:
        """存储缓存项
        Args:
            key: 缓存键
            value: 缓存值
            expiry: 过期时间(秒)
            metadata: 附加元数据
        """
        cache_entry = {
            'data': value,
            'timestamp': time.time(),
            'expiry': expiry,
            'metadata': metadata or {}
        }
        # 添加版本信息
        if self.use_version:
            cache_entry['version'] = self.version
        # 计算校验和
        if self.use_checksum:
            # 先计算除了checksum之外的所有字段
            entry_for_checksum = {k: v for k, v in cache_entry.items()}
            cache_entry['checksum'] = self._calculate_checksum(entry_for_checksum)
        self.cache[key] = cache_entry
        self._save_cache()
        return True
    def retrieve(self, key: str) -> Optional[Any]:
        """检索并验证缓存项"""
        cache_entry = self.cache.get(key)
        if not cache_entry:
            return None
        # 验证完整性
        if self.use_checksum:
            if not self._verify_entry_integrity(key, cache_entry):
                print(f"缓存项 '{key}' 完整性验证失败")
                del self.cache[key]
                self._save_cache()
                return None
        # 检查过期时间
        if cache_entry.get('expiry'):
            elapsed = time.time() - cache_entry['timestamp']
            if elapsed > cache_entry['expiry']:
                del self.cache[key]
                self._save_cache()
                return None
        return cache_entry['data']
    def _verify_entry_integrity(self, key: str, entry: Dict) -> bool:
        """验证单个缓存项完整性"""
        if 'checksum' not in entry:
            return True
        expected_checksum = entry['checksum']
        entry_without_checksum = {k: v for k, v in entry.items() if k != 'checksum'}
        calculated = self._calculate_checksum(entry_without_checksum)
        return calculated == expected_checksum
    def _save_cache(self):
        """保存缓存到文件"""
        try:
            with open(self.cache_file, 'w') as f:
                json.dump(self.cache, f, indent=2)
        except IOError as e:
            print(f"保存缓存失败: {e}")
    def clear_expired(self):
        """清除过期缓存"""
        now = time.time()
        expired_keys = []
        for key, entry in self.cache.items():
            if entry.get('expiry'):
                if now - entry['timestamp'] > entry['expiry']:
                    expired_keys.append(key)
        for key in expired_keys:
            del self.cache[key]
        if expired_keys:
            self._save_cache()
        return len(expired_keys)
# 使用示例
if __name__ == "__main__":
    # 简单使用
    cache = CacheWithHash()
    cache.store_with_hash("user:1", {"name": "张三", "age": 30})
    data = cache.verify_and_retrieve("user:1")
    print(f"获取数据: {data}")
    # 篡改数据测试
    cache.cache["user:1"]["data"]["age"] = 25  # 手动修改
    data = cache.verify_and_retrieve("user:1")
    print(f"篡改后获取数据: {data}")  # 返回None
    # 使用集成缓存管理器
    manager = IntegratedCacheManager()
    manager.store("config", {"db_host": "localhost", "db_port": 3306}, expiry=3600)
    config = manager.retrieve("config")
    print(f"配置数据: {config}")

数据库级别完整性

import sqlite3
import hashlib
from typing import Any, Tuple
class DatabaseCacheWithIntegrity:
    """使用数据库存储缓存并验证完整性"""
    def __init__(self, db_path: str = "cache.db"):
        self.conn = sqlite3.connect(db_path)
        self._create_tables()
    def _create_tables(self):
        """创建数据库表"""
        self.conn.execute("""
            CREATE TABLE IF NOT EXISTS cache (
                key TEXT PRIMARY KEY,
                value TEXT NOT NULL,
                checksum TEXT NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        self.conn.commit()
    def set(self, key: str, value: Any) -> bool:
        """存储缓存项"""
        serialized = str(value)
        checksum = hashlib.md5(serialized.encode()).hexdigest()
        self.conn.execute(
            "INSERT OR REPLACE INTO cache (key, value, checksum) VALUES (?, ?, ?)",
            (key, serialized, checksum)
        )
        self.conn.commit()
        return True
    def get(self, key: str) -> Tuple[bool, Any]:
        """获取并验证缓存项
        Returns:
            (is_valid, value) 元组
        """
        cursor = self.conn.execute(
            "SELECT value, checksum FROM cache WHERE key = ?", 
            (key,)
        )
        row = cursor.fetchone()
        if not row:
            return False, None
        value, stored_checksum = row
        # 验证完整性
        calculated_checksum = hashlib.md5(value.encode()).hexdigest()
        if calculated_checksum != stored_checksum:
            # 数据被篡改
            self.conn.execute("DELETE FROM cache WHERE key = ?", (key,))
            self.conn.commit()
            return False, None
        return True, value

最佳实践建议

  1. 选择适当的校验算法

    • 对于一般用途:MD5或SHA256
    • 对安全性要求高:HMAC-SHA256
    • 对性能要求高:CRC32
  2. 定期验证缓存完整性

  3. 实现缓存失效机制

  4. 记录完整性检查日志

  5. 在分布式环境中使用一致性哈希

这些方法可以单独使用或组合使用,具体取决于你的应用场景和安全需求。

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