如何使用Mysql 8 解密Java Cipher 加密的信息?
How to decrypt information encrypted by Java Cipher using Mysql 8?
上下文
我正在加密来自我的应用程序的信息,然后我将加密的信息保存在我的 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查询解密字符串
SELECT 描述,AES_DECRYPT(描述,'key')来自 test_table;
您的 AttributeConverter 负责数据加密使用 AES/ECB/PKCS5Padding
密码,转换为:
- 使用默认 128 位密钥长度的 AES 加密
- 欧洲央行模式
- PKCS5 填充
为了用 MySQL 的 AES_DECRYPT 解密用上述方法加密的数据,您需要使用相同的设置对其进行配置(知道加密密钥也会有所帮助 ;-) )。在这种情况下,您应该使用:
SET block_encryption_mode = 'aes-128-ecb';
SELECT CAST(AES_DECRYPT(FROM_BASE64(column_name),'encryption_key') as char(64));
示例加密代码:
final String KEY_ENCRYPT_BD = "TEST#EST@#ST!@#T";
final String ALGORITHM = "AES/ECB/PKCS5Padding";
final String data = "Secret";
Key key = new SecretKeySpec(KEY_ENCRYPT_BD.getBytes(), "AES");
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
System.out.println(Base64.getEncoder().encodeToString(c.doFinal(data.getBytes("UTF-8"))));
// Output is: pkIRP/y09TKfv5Y8nPrFRw==
示例解密代码:
SET block_encryption_mode = 'aes-128-ecb';
SELECT cast(Aes_decrypt(From_base64('pkIRP/y09TKfv5Y8nPrFRw=='),'TEST#EST@#ST!@#T') as char(50));
Output 是 Secret
备注:
- 您的
utf8mb4
字符集无关紧要,因为您只存储 base64 字符串。也许 binary 数据类型可以为每条记录节省几个字节(并且完全避免 base64
)。
- 您的 MySQL 5.7 服务器可能已经将
block_encryption_mode
设置为 aes-128-ecb
这解释了为什么解密有效
上下文
我正在加密来自我的应用程序的信息,然后我将加密的信息保存在我的 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查询解密字符串
SELECT 描述,AES_DECRYPT(描述,'key')来自 test_table;
您的 AttributeConverter 负责数据加密使用 AES/ECB/PKCS5Padding
密码,转换为:
- 使用默认 128 位密钥长度的 AES 加密
- 欧洲央行模式
- PKCS5 填充
为了用 MySQL 的 AES_DECRYPT 解密用上述方法加密的数据,您需要使用相同的设置对其进行配置(知道加密密钥也会有所帮助 ;-) )。在这种情况下,您应该使用:
SET block_encryption_mode = 'aes-128-ecb';
SELECT CAST(AES_DECRYPT(FROM_BASE64(column_name),'encryption_key') as char(64));
示例加密代码:
final String KEY_ENCRYPT_BD = "TEST#EST@#ST!@#T";
final String ALGORITHM = "AES/ECB/PKCS5Padding";
final String data = "Secret";
Key key = new SecretKeySpec(KEY_ENCRYPT_BD.getBytes(), "AES");
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
System.out.println(Base64.getEncoder().encodeToString(c.doFinal(data.getBytes("UTF-8"))));
// Output is: pkIRP/y09TKfv5Y8nPrFRw==
示例解密代码:
SET block_encryption_mode = 'aes-128-ecb';
SELECT cast(Aes_decrypt(From_base64('pkIRP/y09TKfv5Y8nPrFRw=='),'TEST#EST@#ST!@#T') as char(50));
Output 是 Secret
备注:
- 您的
utf8mb4
字符集无关紧要,因为您只存储 base64 字符串。也许 binary 数据类型可以为每条记录节省几个字节(并且完全避免base64
)。 - 您的 MySQL 5.7 服务器可能已经将
block_encryption_mode
设置为aes-128-ecb
这解释了为什么解密有效