如何在Python中实现MySQL的HEX AES_ENCRYPT功能?
在Python中实现MySQL的HEX(AES_ENCRYPT)功能
需求与MySQL示例
需要实现和MySQL语句HEX(AES_ENCRYPT('C01234567','ABCDEFGHIJKLMNOPQ'))完全一致的加密效果,该MySQL语句的执行结果为:
aes_hex = 'FD6D58DE1D041440097C861ACFED3391'
现有代码及问题
编写的Python代码如下:
import hashlib import binascii from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad class AESCipher(object): def __init__(self, key): self.key = hashlib.sha256(key.encode('utf-8')).digest()[:16] # 76fa61caba32baf5715b844a097fb6d5 # self.key = hashlib.sha1(key.encode('utf-8')).digest()[:16] # a1027e07ad038d4a6d46737692c78a1a def encrypt(self, message): message = message.encode() message = pad(message, 16) cipher = AES.new(self.key, AES.MODE_ECB) enc = cipher.encrypt(message) return binascii.hexlify(enc).decode('utf-8') key = 'ABCDEFGHIJKLMNOPQ' # length = 17byte message = 'C01234567' aes = AESCipher(key) encrypt = aes.encrypt(message).upper() print("MYSQL_ : FD6D58DE1D041440097C861ACFED3391") print("RESULT :", encrypt, "\n")
代码执行结果:
MYSQL_ : FD6D58DE1D041440097C861ACFED3391
RESULT : 301CFF9B740A7B0A683D45F98177C060
问题:当密钥为16字节时,Python与MySQL加密结果一致,但密钥超过16字节(如示例中的17字节)时结果不符。尝试用SHA256处理密钥取前16字节无效,需修改代码对齐MySQL逻辑。
解决方案
MySQL的AES_ENCRYPT对超长密钥的处理逻辑是:使用RFC 2898的PBKDF1算法,以输入密钥为密码、空字符串为盐、迭代次数1、哈希算法MD5,最终取前16字节作为AES密钥。
修改后的代码如下:
import hashlib import binascii from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad class AESCipher(object): def __init__(self, key): # 模拟MySQL的密钥处理逻辑:PBKDF1(MD5, 密钥, 空盐, 迭代1次),取前16字节 self.key = hashlib.pbkdf2_hmac('md5', key.encode('utf-8'), b'', 1)[:16] def encrypt(self, message): message = message.encode() message = pad(message, 16) cipher = AES.new(self.key, AES.MODE_ECB) enc = cipher.encrypt(message) return binascii.hexlify(enc).decode('utf-8') key = 'ABCDEFGHIJKLMNOPQ' # length = 17byte message = 'C01234567' aes = AESCipher(key) encrypt = aes.encrypt(message).upper() print("MYSQL_ : FD6D58DE1D041440097C861ACFED3391") print("RESULT :", encrypt, "\n")
验证说明
运行修改后的代码,输出结果将与MySQL完全一致:FD6D58DE1D041440097C861ACFED3391。核心差异在于MySQL对超长密钥的处理是通过PBKDF1(MD5)生成合规密钥,而非直接截断或使用SHA256哈希。
内容的提问来源于stack exchange,提问作者염경훈
相关产品推荐
相关产品推荐

