如何在MySQL 8中解密Java Cipher AES/ECB/PKCS5Padding加密的数据
问题背景
我在应用程序中对信息加密后存储到MySQL 8.0数据库,应用中的加解密实现代码如下:
private static final String ALGORITHM = "AES/ECB/PKCS5Padding"; @Override public String convertToDatabaseColumn(String data) { if (data != null) { Key key = new SecretKeySpec(KEY_ENCRYPT_BD.getBytes(), "AES"); try { Cipher c = Cipher.getInstance(ALGORITHM); c.init(Cipher.ENCRYPT_MODE, key); return Base64.getEncoder().encodeToString(c.doFinal(data.getBytes("UTF-8"))); } catch (Exception e) { throw new RuntimeException(e); } } return null; } @Override public String convertToEntityAttribute(String dbData) { if (dbData != null) { Key key = new SecretKeySpec(KEY_ENCRYPT_BD.getBytes(), "AES"); try { Cipher c = Cipher.getInstance(ALGORITHM); c.init(Cipher.DECRYPT_MODE, key); return new String(c.doFinal(Base64.getDecoder().decode(dbData.getBytes("UTF-8"))), "UTF-8"); } catch (Exception e) { return dbData; } } return null; }
加密后的信息存储在字符集为utf8mb4的varchar(65)字段中。
需求说明
我希望直接通过MySQL 8.0解密上述加密信息,尝试了多种复现Java加解密流程的方式,最终都只返回Null结果,我使用的查询语句如下:
SELECT AES_DECRYPT(FROM_BASE64(primer_nombre),'passwordKey') FROM info_personal_usuario;
参考信息
我在MySQL 5.7中可以使用以下查询语句成功解密数据:
SELECT Cast(Aes_decrypt(From_base64(primer_nombre),"passwordkey") AS CHAR(50)) primer_nombre FROM info_personal_usuario
已尝试方案
我尝试修改加密模式适配,相关执行语句如下,依然未能成功解密:
SET block_encryption_mode = 'aes-256-cbc'; SET @init_vector = RANDOM_BYTES(16); SET @key_str = SHA2('pwdKey',512); SELECT Cast(Aes_decrypt(From_base64(primer_nombre),@key_str,@init_vector) AS CHAR(50)) primer_nombre FROM info_personal_usuario;
解决方案
解密失败的核心原因是MySQL 8.0和5.7的默认加密配置不同,且之前尝试的修改方向和Java原始加密逻辑不匹配:
- Java用的是AES/ECB/PKCS5Padding加密模式,不需要初始化向量(IV),也没有对密钥做SHA2哈希处理,之前切换到CBC模式、生成IV、哈希密钥的操作完全不符合原始加密逻辑,必然解密失败
- MySQL 5.7默认
block_encryption_mode为aes-128-ecb,和Java加密模式匹配,所以可以直接解密;MySQL 8.0默认block_encryption_mode改为aes-256-cbc,模式不匹配所以返回NULL
正确的解密操作步骤如下:
- 首先显式设置加密模式和Java使用的模式对齐,注意密钥长度对应:如果Java密钥
KEY_ENCRYPT_BD字节长度为16则用aes-128-ecb,24字节用aes-192-ecb,32字节用aes-256-ecb
SET block_encryption_mode = 'aes-128-ecb';
- 执行解密查询,注意密钥必须和Java代码中的
KEY_ENCRYPT_BD完全一致(大小写、特殊字符都不能有差异),转字符串时指定对应字符集:
SELECT CAST(AES_DECRYPT(FROM_BASE64(primer_nombre), '你的实际密钥字符串') AS CHAR(50) CHARSET utf8mb4) AS primer_nombre FROM info_personal_usuario;
额外提示
ECB模式安全性较低,后续业务迭代时建议升级为CBC模式搭配随机IV存储,提升加密数据安全性。
内容的提问来源于stack exchange,提问作者Julian Solarte
相关产品推荐
相关产品推荐

