如何在Python中解密旧版OpenSSL 3DES加密数据以完成MySQL迁移
OpenSSL enc 带盐格式结构拆解
Base64解码后得到的Salted__开头字节串,是OpenSSL enc命令默认的带盐加密格式,结构固定为:
- 前8字节:固定ASCII标识
Salted__,无实际加密作用 - 紧随的8字节:随机盐值,用于派生密钥时削弱彩虹表攻击风险
- 剩余全部字节:3DES-CBC模式的实际密文
密钥与IV的派生逻辑
现有解密命令openssl enc -des3 -md md5 -a -A -pass pass:<PASSPHRASE> -d对应的派生逻辑,完全遵循OpenSSL内部EVP_BytesToKey规则,无额外黑盒:
- 从解码的字节串中提取8字节盐值(跳过开头的
Salted__标识位) - 3DES加密需要24字节密钥、CBC模式需要8字节初始化向量(IV),共需凑集32字节派生材料
- 派生计算流程:
- 第一轮:计算MD5摘要,输入内容为「密码短语原始字节 + 提取到的8字节盐值」,得到16字节摘要块
- 第二轮:因单轮MD5仅输出16字节,未达到32字节的总需求,继续计算MD5摘要,输入内容为「上一轮的16字节摘要块 + 密码短语原始字节 + 提取到的8字节盐值」,再得到16字节摘要块
- 拼接两轮摘要块为32字节总派生材料:前24字节为3DES密钥,后8字节为CBC模式IV
无系统命令依赖的Python解密实现
基于cryptography库实现的解密逻辑,与OpenSSL命令解密结果完全一致:
import base64 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import hashes from cryptography.hazmat.backends import default_backend # 替换为实际业务值 ENCODED_DATA = "旧库中存储的Base64加密串" PASSPHRASE = b"旧系统使用的加密密码短语" # Base64解码原始存储内容 decoded_raw = base64.b64decode(ENCODED_DATA) # 校验OpenSSL带盐格式 if not decoded_raw.startswith(b"Salted__"): raise ValueError("存储内容不符合OpenSSL带盐加密格式") # 拆分盐值与密文 salt = decoded_raw[8:16] ciphertext = decoded_raw[16:] # 按OpenSSL规则派生密钥与IV derived_material = b"" previous_digest = b"" required_derived_len = 32 # 24字节3DES密钥 + 8字节CBC IV while len(derived_material) < required_derived_len: md5 = hashes.Hash(hashes.MD5(), backend=default_backend()) md5.update(previous_digest + PASSPHRASE + salt) current_digest = md5.finalize() derived_material += current_digest previous_digest = current_digest # 拆分密钥与IV key = derived_material[:24] iv = derived_material[24:32] # 3DES-CBC解密 cipher = Cipher(algorithms.TripleDES(key), modes.CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize() # 移除OpenSSL默认的PKCS#7填充 padding_length = padded_plaintext[-1] plaintext = padded_plaintext[:-padding_length]
落地注意事项
- 密码短语编码需与旧系统完全匹配:如果旧系统使用GBK/GB2312编码存储密码,不要强制转成UTF-8,否则派生密钥会完全错误
- 模式匹配:旧OpenSSL的
des3参数默认对应3DES-EDE-CBC模式,与cryptography库的TripleDES默认行为完全一致,无需额外调整 - 库兼容性:如果选择使用oscrypto而非cryptography,上述密钥、IV的派生逻辑完全通用,仅需替换对应的解密接口调用即可
- 现代加密迁移:解密得到明文后,直接使用AES-256-GCM等现代加密算法重新加密存储即可,无需沿用旧的3DES+MD5弱加密逻辑
内容的提问来源于stack exchange,提问作者teknofyl
相关产品推荐
相关产品推荐

