如何让MariaDB的AES_ENCRYPT函数返回32字节的加密结果
如何让MariaDB的AES_ENCRYPT函数返回32字节的加密结果
我来帮你理清这个问题~首先得搞清楚核心差异:你Java代码里得到的32字节加密结果,并不是单纯的AES加密密文,而MariaDB的AES_ENCRYPT只返回了纯密文部分,这才是长度不一样的原因。
为什么长度差这么多?
AES算法的块大小是固定16字节——不管你用128、192还是256位密钥,单块加密后的密文都是16字节。你的明文“Original String”是15字节,PKCS#5填充后刚好占1块(16字节),所以加密后的纯密文就是16字节。
而你Java里的32字节结果,其实是16字节的初始化向量(IV) + 16字节的纯密文拼接出来的!Spring的AesBytesEncryptor在CBC模式下会自动生成随机IV,然后把IV和密文绑在一起输出,转成Hex后就变成了64字符的字符串。
怎么在MariaDB里生成32字节的结果?
你需要手动生成随机IV,加密得到纯密文后,把IV和密文拼接起来,这样总长度就是32字节了。具体操作如下:
- 生成随机16字节IV(AES-CBC的IV长度必须等于块大小16字节)
- 用该IV加密明文得到纯密文
- 拼接IV和密文,再转成Hex格式
对应的SQL代码示例:
-- 生成随机16字节IV SET @random_iv = RANDOM_BYTES(16); -- 用指定密钥、IV和AES-256-CBC模式加密明文 SET @cipher_text = AES_ENCRYPT('Original String', 'secretkey', @random_iv, 'aes-256-cbc'); -- 拼接IV和密文,转成Hex得到64字符的结果(对应32字节二进制数据) SELECT HEX(CONCAT(@random_iv, @cipher_text));
额外注意:和Java密钥生成对齐
如果你Java里的secretKey不是直接用的32字节原始密钥,而是通过PBKDF2从密码和盐推导出来的(Spring的Encryptors.text默认就是这么做的),那你得在MariaDB里先还原这个密钥推导过程,才能得到和Java完全一致的加密结果。
比如Spring默认的PBKDF2参数是:迭代次数1024、密钥长度32字节(256位)、哈希算法SHA-1,对应的MariaDB代码:
-- 从密码和盐生成和Java一致的AES密钥 SET @aes_key = PBKDF2('secretKey', '你的盐值', 1024, 32, 'SHA1'); -- 后续加密步骤和上面一样 SET @random_iv = RANDOM_BYTES(16); SET @cipher_text = AES_ENCRYPT('Original String', @aes_key, @random_iv, 'aes-256-cbc'); SELECT HEX(CONCAT(@random_iv, @cipher_text));
这样得到的结果就是和Java格式完全一致的32字节二进制数据(转Hex后64字符)啦!
备注:内容来源于stack exchange,提问作者Gigi
相关产品推荐
相关产品推荐

