使用MySQL AES_ENCRYPT加密数据保存失败,如何解决?
解决方法
1. 修正SQL语法错误
你的UPDATE语句里AES_ENCRYPT('{token}', '{key}'), WHERE多了一个逗号,这会直接导致SQL语法错误,先把这个逗号删掉。
2. 调整字段存储类型
AES_ENCRYPT函数返回的是二进制数据,如果你的token字段是VARCHAR/TEXT这类字符型类型,就会因为二进制字节不符合字符编码规则报错。需要把字段改成二进制类型:
执行以下SQL修改表结构(根据实际需求选择类型):
-- 推荐用VARBINARY,指定足够长度(比如256,可根据加密后数据长度调整) ALTER TABLE `table` MODIFY COLUMN token VARBINARY(256); -- 或者用BLOB(适合不确定长度的情况) ALTER TABLE `table` MODIFY COLUMN token BLOB;
3. 替换SQL拼接为参数化查询
你当前用f-string拼接SQL存在严重的SQL注入风险,同时也可能因为字符串转义问题导致错误。改用mysql.connector支持的参数化查询:
修正后的Python代码:
import hashlib # 生成密钥(hexdigest返回64位十六进制字符串,对应32字节,符合AES-256要求) key = hashlib.sha256(str(guild.owner_id).encode('utf-8')).hexdigest() # 参数化查询,用%s作为占位符,避免SQL注入 update_sql = '''UPDATE `table` SET token = AES_ENCRYPT(%s, %s) WHERE id = %s''' # 传递参数元组,cursor会自动处理类型转义 cursor.execute(update_sql, (token, key, guild.id)) connection.commit()
补充说明
- 若想使用二进制密钥而非字符串密钥,可把
hexdigest()换成digest(),直接得到32字节二进制数据,传递给AES_ENCRYPT时更高效:key = hashlib.sha256(str(guild.owner_id).encode('utf-8')).digest() - 解密时用AES_DECRYPT函数,记得处理NULL情况(比如密钥不正确时返回NULL):
SELECT AES_DECRYPT(token, %s) FROM `table` WHERE id = %s
内容的提问来源于stack exchange,提问作者user22936811
相关产品推荐
相关产品推荐

