针对第三方与己方共用 SQL Server 账户(包括 sa)且可能共用服务器的场景,以下是基于 Python 的业务数据加密与排他性功能方案,通过 “数据加密 + 身份识别 + 操作拦截” 三层防护实现安全隔离:
1. 业务数据加密:防止敏感信息泄露
1.1. 数据库端准备(创建加密所需对象)
1.2. Python 端加密 / 解密实现(核心代码)
import pyodbc import datetime from typing import Optional class SQLDataSecurity: def __init__(self, conn_str: str, sym_key_password: str): """ 初始化数据库连接和加密配置 :param conn_str: SQL Server连接字符串 :param sym_key_password: 对称密钥保护密码(仅应用层持有) """ self.conn_str = conn_str self.sym_key_name = "BizSymKey" self.cert_name = "BizDataCert" self.sym_key_password = sym_key_password # 关键:不存储在数据库,由程序管理 def _get_connection(self) -> pyodbc.Connection: """获取数据库连接""" return pyodbc.connect(self.conn_str) def encrypt_data(self, plaintext: str) -> Optional[bytes]: """ 加密明文数据(如手机号) :param plaintext: 明文数据 :return: 加密后的二进制数据 """ conn = None try: conn = self._get_connection() cursor = conn.cursor() # 1. 打开对称密钥(需证书解密) cursor.execute(f""" OPEN SYMMETRIC KEY {self.sym_key_name} DECRYPTION BY CERTIFICATE {self.cert_name}; """) # 2. 加密数据(使用对称密钥) cursor.execute(f""" SELECT EncryptByKey(Key_GUID('{self.sym_key_name}'), ?) AS encrypted_data; """, (plaintext,)) result = cursor.fetchone() return result.encrypted_data if result else None except Exception as e: print(f"加密失败: {str(e)}") return None finally: if conn: # 关闭对称密钥 cursor.execute(f"CLOSE SYMMETRIC KEY {self.sym_key_name};") conn.close() def decrypt_data(self, encrypted_data: bytes) -> Optional[str]: """ 解密密文数据 :param encrypted_data: 加密后的二进制数据 :return: 解密后的明文 """ conn = None try: conn = self._get_connection() cursor = conn.cursor() # 1. 打开对称密钥 cursor.execute(f""" OPEN SYMMETRIC KEY {self.sym_key_name} DECRYPTION BY CERTIFICATE {self.cert_name}; """) # 2. 解密数据 cursor.execute(f""" SELECT CONVERT(NVARCHAR(100), DecryptByKey(?)) AS decrypted_data; """, (encrypted_data,)) result = cursor.fetchone() return result.decrypted_data if result else None except Exception as e: print(f"解密失败: {str(e)}") return None finally: if conn: cursor.execute(f"CLOSE SYMMETRIC KEY {self.sym_key_name};") conn.close() # 示例用法 if __name__ == "__main__": # 连接字符串(注意:实际使用中从安全配置中心获取) CONNECTION_STR = ( "DRIVER={ODBC Driver 17 for SQL Server};" "SERVER=your_server;" "DATABASE=YourDatabase;" "UID=shared_user;" # 共用的数据库账户 "PWD=shared_password;" ) # 对称密钥保护密码(仅己方程序知晓,不存储在数据库) SYM_KEY_PASSWORD = "YourSecureKey123!" # 实际应使用更复杂的密钥 # 初始化加密工具 security = SQLDataSecurity(CONNECTION_STR, SYM_KEY_PASSWORD) # 加密示例:存储手机号 plaintext_phone = "13800138000" encrypted_phone = security.encrypt_data(plaintext_phone) if encrypted_phone: # 插入数据库 conn = pyodbc.connect(CONNECTION_STR) cursor = conn.cursor() cursor.execute("INSERT INTO Users (username, phone_encrypted) VALUES (?, ?);", ("张三", encrypted_phone)) conn.commit() conn.close() print(f"加密后存储: {encrypted_phone.hex()}") # 解密示例:读取手机号 conn = pyodbc.connect(CONNECTION_STR) cursor = conn.cursor() cursor.execute("SELECT phone_encrypted FROM Users WHERE username = '张三';") encrypted_data = cursor.fetchone()[0] conn.close() decrypted_phone = security.decrypt_data(encrypted_data) print(f"解密后: {decrypted_phone}") # 输出:13800138000
posted on
浙公网安备 33010602011771号