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

MySQL与Java AES-256-CBC加解密互操作问题咨询

解密失败核心原因

你解密不成功是两个参数对齐问题导致的:

  • 密钥格式不匹配:你当前Java代码用toString()获取的是SHA-256哈希的十六进制字符串(长度64字节),但MySQL的SHA2()函数直接返回32字节长度的原始二进制哈希值,刚好是AES-256要求的256位密钥长度,二者字节级完全不一致,必然解密失败。
  • 加密配置未对齐:没有严格匹配MySQL使用的IV、填充规则。
实现方案

不需要依赖Bouncy Castle,JDK自带的加密API就可以实现,只要严格对齐以下规则即可:

  • 密钥生成:调用Guava哈希工具的asBytes()方法,直接获取32字节的原始SHA-256哈希值作为密钥,不要用toString()转十六进制字符串。
  • IV配置:MySQLaes_encrypt的第三个参数就是CBC模式的初始化向量,直接将你传入的字符串ssshhhhhhhhhhh!!以UTF-8编码转成字节数组作为IV即可,长度刚好为AES要求的16字节。
  • 算法与填充:算法模式指定为AES/CBC/PKCS5Padding,MySQL的aes-256-cbc默认使用PKCS7填充,Java中块大小为16字节时PKCS5Padding与PKCS7完全兼容,可以直接使用。
  • 密文处理:MySQL侧加密结果是二进制,通过to_base64()转成了Base64字符串,Java端解密前先对Base64串解码得到原始密文字节数组,解密后再转成UTF-8字符串即可得到明文。
可直接运行的代码示例
import com.google.common.hash.Hashing;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class MysqlAesUtil {
    public static void main(String[] args) throws Exception {
        // 生成和MySQL字节级一致的AES-256密钥
        byte[] keyBytes = Hashing.sha256()
                .hashString("ssshhhhhhhhhhh!!ENCRYPTION_KEY$&", StandardCharsets.UTF_8)
                .asBytes();
        SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");

        // 构造和MySQL一致的IV
        byte[] ivBytes = "ssshhhhhhhhhhh!!".getBytes(StandardCharsets.UTF_8);
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        // 初始化解密器
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);

        // 测试解密你给出的示例密文
        String cipherTextBase64 = "StThdNXA+CWvlg+of/heJQ==";
        byte[] cipherBytes = Base64.getDecoder().decode(cipherTextBase64);
        byte[] plainBytes = cipher.doFinal(cipherBytes);
        System.out.println(new String(plainBytes, StandardCharsets.UTF_8));
        // 输出结果为 test_value
    }
}
注意事项
  • JDK8u161及以上版本默认支持AES-256加密,不需要修改加密策略文件;低版本JDK如果报密钥长度非法,需要替换JRE目录下的无限制加密策略文件。
  • 不要对密钥、IV做任何额外的哈希、补位转换,保证和MySQL侧传入值的字节序列完全一致即可。
  • 加密操作和上述逻辑一致,只要把Cipher初始化模式改成ENCRYPT_MODE,最后对加密结果做Base64编码,就能得到和MySQLto_base64(aes_encrypt(...))完全一致的输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 23:03:30