本文目录导读:

我来详细介绍Python操作数据库加密列的几种常见方法:
应用层加密(推荐方式)
使用Python加密库
import pymysql
from cryptography.fernet import Fernet
import base64
import hashlib
class DatabaseEncryptor:
def __init__(self, encryption_key):
# 生成或使用预设密钥
if isinstance(encryption_key, str):
# 将字符串密钥转换为Fernet格式
key = base64.urlsafe_b64encode(
hashlib.sha256(encryption_key.encode()).digest()
)
else:
key = encryption_key
self.cipher = Fernet(key)
def encrypt_data(self, plaintext):
"""加密数据"""
if plaintext is None:
return None
return self.cipher.encrypt(plaintext.encode()).decode()
def decrypt_data(self, ciphertext):
"""解密数据"""
if ciphertext is None:
return None
return self.cipher.decrypt(ciphertext.encode()).decode()
# 使用示例
class UserDatabase:
def __init__(self, connection, encryptor):
self.conn = connection
self.encryptor = encryptor
def insert_encrypted_user(self, user_data):
cursor = self.conn.cursor()
# 加密敏感字段
encrypted_email = self.encryptor.encrypt_data(user_data['email'])
encrypted_phone = self.encryptor.encrypt_data(user_data['phone'])
sql = """INSERT INTO users (username, email_encrypted, phone_encrypted)
VALUES (%s, %s, %s)"""
cursor.execute(sql, (
user_data['username'],
encrypted_email,
encrypted_phone
))
self.conn.commit()
def get_decrypted_user(self, user_id):
cursor = self.conn.cursor()
cursor.execute("SELECT username, email_encrypted, phone_encrypted FROM users WHERE id = %s", (user_id,))
row = cursor.fetchone()
if row:
return {
'username': row[0],
'email': self.encryptor.decrypt_data(row[1]),
'phone': self.encryptor.decrypt_data(row[2])
}
return None
使用SQLAlchemy ORM + 自定义类型
from sqlalchemy import create_engine, Column, String, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from cryptography.fernet import Fernet
import json
Base = declarative_base()
class EncryptedString:
"""自定义加密字段类型"""
impl = String
def __init__(self, encryption_key):
self.cipher = Fernet(encryption_key)
def process_bind_param(self, value, dialect):
"""存储前加密"""
if value is not None:
return self.cipher.encrypt(value.encode()).decode()
return None
def process_result_value(self, value, dialect):
"""读取时解密"""
if value is not None:
return self.cipher.decrypt(value.encode()).decode()
return None
# 定义模型
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String(50))
# 使用自定义加密类型
@property
def email(self):
return self._email_decrypted
@email.setter
def email(self, value):
self._email_encrypted = self.encrypt(value)
self._email_decrypted = value
# 或者使用混合属性
from sqlalchemy.ext.hybrid import hybrid_property
@hybrid_property
def encrypted_email(self):
return self._email_encrypted
# 完整实现示例
from sqlalchemy import event
from sqlalchemy.orm import mapper
class EncryptedModel:
"""加密模型基类"""
def __init__(self, encryption_key):
self.encryptor = Fernet(encryption_key)
def encrypt(self, value):
if value is None:
return None
return self.encryptor.encrypt(value.encode()).decode()
def decrypt(self, value):
if value is None:
return None
return self.encryptor.decrypt(value.encode()).decode()
# 使用示例
def create_user_with_encryption():
engine = create_engine('mysql+pymysql://user:pass@localhost/db')
Session = sessionmaker(bind=engine)
session = Session()
# 初始化加密器
encryptor = EncryptedModel(b'your-encryption-key-here')
# 创建用户
new_user = User()
new_user.username = 'test_user'
new_user._email_encrypted = encryptor.encrypt('test@example.com')
session.add(new_user)
session.commit()
使用MySQL内置加密函数
import pymysql
from pymysql.cursors import DictCursor
class MySQLEncryptionExample:
def __init__(self, connection_config):
self.connection = pymysql.connect(**connection_config)
def insert_with_aes_encrypt(self, data):
cursor = self.connection.cursor()
sql = """INSERT INTO encrypted_table
(encrypted_data)
VALUES (AES_ENCRYPT(%s, 'your-secret-key'))"""
cursor.execute(sql, (data['sensitive_info'],))
self.connection.commit()
def read_with_aes_decrypt(self, record_id):
cursor = self.connection.cursor(DictCursor)
sql = """SELECT id,
AES_DECRYPT(encrypted_data, 'your-secret-key') as decrypted_data
FROM encrypted_table
WHERE id = %s"""
cursor.execute(sql, (record_id,))
result = cursor.fetchone()
if result:
# 注意:AES_DECRYPT返回bytes类型
result['decrypted_data'] = result['decrypted_data'].decode('utf-8')
return result
最佳实践示例
import os
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import base64
import pymysql
from pymysql.cursors import DictCursor
class SecureDatabaseHandler:
def __init__(self, db_config, encryption_key_env_var='DB_ENCRYPTION_KEY'):
# 从环境变量获取密钥
encryption_key = os.environ.get(encryption_key_env_var)
if not encryption_key:
raise ValueError(f"Environment variable {encryption_key_env_var} not set")
# 生成密钥
self.encryption_key = self.derive_key(encryption_key)
self.cipher = Fernet(self.encryption_key)
# 数据库连接
self.connection = pymysql.connect(**db_config)
def derive_key(self, password, salt=None):
"""从密码派生加密密钥"""
if salt is None:
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
)
key = base64.urlsafe_b64encode(kdf.derive(password.encode()))
return key
def rotate_encryption_key(self, new_key):
"""轮换加密密钥"""
cursor = self.connection.cursor(DictCursor)
# 获取所有加密数据
cursor.execute("SELECT id, encrypted_data FROM sensitive_table")
older_records = cursor.fetchall()
# 创建新加密器
old_cipher = self.cipher
new_cipher = Fernet(new_key)
# 重新加密所有数据
for record in older_records:
decrypted_data = old_cipher.decrypt(record['encrypted_data'].encode())
re_encrypted_data = new_cipher.encrypt(decrypted_data)
cursor.execute(
"UPDATE sensitive_table SET encrypted_data = %s WHERE id = %s",
(re_encrypted_data.decode(), record['id'])
)
self.connection.commit()
self.cipher = new_cipher
def search_encrypted_field(self, search_value):
"""搜索加密字段(只能精确匹配)"""
cursor = self.connection.cursor(DictCursor)
# 加密搜索值
encrypted_search = self.cipher.encrypt(search_value.encode()).decode()
cursor.execute(
"SELECT * FROM sensitive_table WHERE encrypted_data = %s",
(encrypted_search,)
)
results = cursor.fetchall()
# 解密结果
for result in results:
result['decrypted_data'] = self.cipher.decrypt(
result['encrypted_data'].encode()
).decode()
return results
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self.connection:
self.connection.close()
安全注意事项
# 密钥管理示例
class KeyManagement:
def __init__(self):
self.key_store = {}
def store_key(self, key_id, key):
"""安全存储密钥"""
# 使用密钥管理服务(如AWS KMS, Azure Key Vault)
# 或加密存储到配置文件
encrypted_key = self.encrypt_with_master_key(key)
self.key_store[key_id] = encrypted_key
def get_key(self, key_id):
"""获取解密后的密钥"""
encrypted_key = self.key_store.get(key_id)
if encrypted_key:
return self.decrypt_with_master_key(encrypted_key)
return None
def rotate_keys(self):
"""定期轮换密钥"""
# 实现密钥轮换逻辑
pass
# 使用环境变量管理密钥
import os
from dotenv import load_dotenv
load_dotenv()
# 数据库配置
db_config = {
'host': os.getenv('DB_HOST'),
'user': os.getenv('DB_USER'),
'password': os.getenv('DB_PASSWORD'),
'database': os.getenv('DB_NAME'),
}
# 加密密钥(从环境变量获取)
encryption_key = os.getenv('ENCRYPTION_KEY')
- 应用层加密:最灵活,推荐使用
cryptography库 - ORM加密:使用SQLAlchemy自定义类型
- 数据库函数:使用MySQL的AES_ENCRYPT/AES_DECRYPT
- 密钥管理:从环境变量或密钥管理服务获取
- 性能考虑:加密会增加查询和存储开销
选择哪种方法取决于你的具体需求、安全要求和性能考虑。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播