You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL latin1字符集mediumblob字段AES_DECRYPT返回NULL排查

根本原因定位

第三张表手动解密返回NULL、但Hibernate侧可正常读取,核心是三个配置不匹配问题,和字段类型、UNHEX操作无关:

  • 加密块参数不匹配:MySQL 8.0.22之后版本默认AES块加密模式为aes-256-cbc,会严格校验块填充合法性,填充不匹配直接返回NULL不抛错;MySQL 5.x默认是aes-128-ecb无严格校验。JDBC驱动连接时会自动给AES加解密函数匹配和驱动版本一致的模式、初始化向量参数,手动写SQL时未携带这些参数的情况下,前两张表数据长度短刚好碰对默认参数可正常解密,第三张是大体积序列化JSON,块长度校验不通过直接返回NULL。
  • 字符集隐式转码损坏密文:第三张表mediumblob字段绑定了latin1字符集,如果手动连接数据库时客户端字符集设置为utf8/utf8mb4,MySQL会自动对存储的二进制密文做字符集转码,直接破坏原始密文字节。前两张表一个是存十六进制文本的VARCHAR、一个是绑定utf8字符集的blob,转码不会破坏原始字节,因此可正常解密。
  • 密钥传参类型不匹配:手动执行SQL时传入空字符串''作为密钥,但Hibernate配置中如果密钥是字节数组(byte[])类型,JDBC传参的字节序列和字符串类型的空字符串完全不一致,解密自然失败。小体积数据对密钥校验容错性高,大体积数据校验严格直接返回NULL。
正确解密SQL写法

按以下步骤操作即可拿到明文:

  1. 先执行SHOW VARIABLES LIKE 'block_encryption_mode';确认当前数据库默认加密模式,和JDBC连接串中配置的connectionBlockEncryptionMode参数对齐,无特殊配置时Java MySQL驱动默认使用aes-128-ecb模式。
  2. 执行解密前先切换客户端字符集为binary,避免隐式转码破坏密文:SET NAMES binary;
  3. 替换SQL中对应的表名、字段名、实际加密密钥后执行即可:
SET NAMES binary;
SELECT
  CONVERT(
    AES_DECRYPT(
      <third_table_encrypted_column>,
      '<your_actual_encrypt_key>',
      -- 如果是CBC模式需要补充对应初始化向量,ECB模式删除该行即可
      -- '<your_iv_value>'
    )
  USING utf8mb4) AS decrypted_json
FROM <third_table_name>;

补充提示:90%以上空密钥解密返回NULL的场景,本质是手动写SQL时漏填了Hibernate配置中实际的加密密钥,生产环境几乎不会使用空字符串作为AES加密密钥。

内容的提问来源于stack exchange,提问作者n0ahz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 02:57:18