使用Python加密表格conversationID列时相同值加密结果不一致如何解决
问题根因
- Fernet加密的设计默认携带随机初始化向量(IV)和时间戳,每次调用
encrypt()方法都会生成新的随机参数,因此即便明文、密钥完全一致,每次输出的密文也会不同。 - 你当前代码中每次运行都会调用
Fernet.generate_key()生成新密钥,即使加密逻辑不变,不同次运行的加密结果也会不一致。
解决方案
根据你是否需要将加密结果解密回原始conversationID,可选两种实现方案:
方案1:需要解密回原始ID,采用确定性对称加密
用固定IV的AES加密实现,密钥和IV生成一次后持久化存储,后续加密解密均使用同一组值即可保证同明文同密文。
示例代码如下:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import os # 第一步:首次运行生成密钥和IV,生成后保存到安全位置,后续直接读取使用,不要每次生成 # key = os.urandom(32) # 256位密钥 # iv = os.urandom(16) # AES块大小固定16字节 # 实际使用时替换为你自己存储的固定key和iv key = b'你持久化存储的256位密钥' iv = b'你持久化存储的16字节IV' def encrypt_conversation_id(conversation_id: str, key: bytes, iv: bytes) -> bytes: # 明文长度需要是16的倍数,这里用PKCS7填充 from cryptography.hazmat.primitives import padding padder = padding.PKCS7(128).padder() padded_data = padder.update(conversation_id.encode()) + padder.finalize() cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() return encryptor.update(padded_data) + encryptor.finalize() # 调用示例 for m in TRF: conversation_id = str(m.ConversationID) encrypted = encrypt_conversation_id(conversation_id, key, iv) print(encrypted)
注意:该方案下IV不能随意更换,且仅适合conversationID无法被暴力枚举的场景,避免泄露明文规律。
方案2:不需要解密,仅需唯一映射,采用加盐哈希
如果不需要还原原始conversationID,用固定盐的SHA256哈希实现更简单,性能更高,也能保证同ID输出相同结果:
import hashlib # 固定盐值,生成后持久化存储,不要每次更改 SALT = b'你自定义的固定盐字符串' def hash_conversation_id(conversation_id: str, salt: bytes) -> str: return hashlib.sha256(salt + conversation_id.encode()).hexdigest() # 调用示例 for m in TRF: conversation_id = str(m.ConversationID) encrypted_id = hash_conversation_id(conversation_id, SALT) print(encrypted_id)
内容的提问来源于stack exchange,提问作者Chaa MH
相关产品推荐
相关产品推荐

