如何使用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));

OutputSecret

备注:

  • 您的 utf8mb4 字符集无关紧要,因为您只存储 base64 字符串。也许 binary 数据类型可以为每条记录节省几个字节(并且完全避免 base64)。
  • 您的 MySQL 5.7 服务器可能已经将 block_encryption_mode 设置为 aes-128-ecb 这解释了为什么解密有效