Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AES_DECRYPT在linux上不工作:可能链接到Hibernate_Java_Mysql_Hibernate_Aes_Environment - Fatal编程技术网

Java AES_DECRYPT在linux上不工作:可能链接到Hibernate

Java AES_DECRYPT在linux上不工作:可能链接到Hibernate,java,mysql,hibernate,aes,environment,Java,Mysql,Hibernate,Aes,Environment,我的数据库中有加密的数据,我正在尝试执行一个请求,该请求允许我在phpmyadmin中以明文形式显示值 我使用以下请求: SELECT CAST(AES_DECRYPT(`my_encrypted_colum`, UNHEX('pass_in_hexa') AS CHAR) AS clear_value FROM `my_table` 当我在开发环境(windows)上使用它时,它运行良好。但是一旦我在pre-prod环境(linux)上使用它,我就会得到所有值的NULL 我很确定这和不

我的数据库中有加密的数据,我正在尝试执行一个请求,该请求允许我在phpmyadmin中以明文形式显示值

我使用以下请求:

 SELECT CAST(AES_DECRYPT(`my_encrypted_colum`, UNHEX('pass_in_hexa') AS CHAR) AS clear_value 
 FROM `my_table`
当我在开发环境(windows)上使用它时,它运行良好。但是一旦我在pre-prod环境(linux)上使用它,我就会得到所有值的NULL

我很确定这和不同的环境有关,但我不知道是什么。我甚至不知道哪个函数没有按预期工作:UNHEX或AES_DECRYPT(我猜是UNHEX)

以下是my dev和Prepod环境的配置:

开发人员

Serveur : localhost via TCP/IP
Type de serveur : MySQL
Version du serveur : 5.6.15-log - MySQL Community Server (GPL)
Version du protocole : 10
Utilisateur : root@localhost
Jeu de caractères du serveur : UTF-8 Unicode (utf8)

Apache/2.2.25 (Win32) PHP/5.3.19
Version du client de base de données : libmysql - mysqlnd 5.0.8-dev -     20102224 - $Id: 65fe78e70ce53d27a6cd578597722950e490b0d0 $
Extension PHP : mysqli 
Serveur: Localhost via UNIX socket
Logiciel: MySQL
Version du logiciel: 5.6.14 - MySQL Community Server (GPL)
Version du protocole: 10
Utilisateur: root@localhost
Jeu de caractères du serveur: UTF-8 Unicode (utf8)

Apache/2.2.15 (CentOS)
Version du client de base de données: libmysql - 5.1.72
Extension PHP: mysqli 
prepod

Serveur : localhost via TCP/IP
Type de serveur : MySQL
Version du serveur : 5.6.15-log - MySQL Community Server (GPL)
Version du protocole : 10
Utilisateur : root@localhost
Jeu de caractères du serveur : UTF-8 Unicode (utf8)

Apache/2.2.25 (Win32) PHP/5.3.19
Version du client de base de données : libmysql - mysqlnd 5.0.8-dev -     20102224 - $Id: 65fe78e70ce53d27a6cd578597722950e490b0d0 $
Extension PHP : mysqli 
Serveur: Localhost via UNIX socket
Logiciel: MySQL
Version du logiciel: 5.6.14 - MySQL Community Server (GPL)
Version du protocole: 10
Utilisateur: root@localhost
Jeu de caractères du serveur: UTF-8 Unicode (utf8)

Apache/2.2.15 (CentOS)
Version du client de base de données: libmysql - 5.1.72
Extension PHP: mysqli 
编辑

Serveur : localhost via TCP/IP
Type de serveur : MySQL
Version du serveur : 5.6.15-log - MySQL Community Server (GPL)
Version du protocole : 10
Utilisateur : root@localhost
Jeu de caractères du serveur : UTF-8 Unicode (utf8)

Apache/2.2.25 (Win32) PHP/5.3.19
Version du client de base de données : libmysql - mysqlnd 5.0.8-dev -     20102224 - $Id: 65fe78e70ce53d27a6cd578597722950e490b0d0 $
Extension PHP : mysqli 
Serveur: Localhost via UNIX socket
Logiciel: MySQL
Version du logiciel: 5.6.14 - MySQL Community Server (GPL)
Version du protocole: 10
Utilisateur: root@localhost
Jeu de caractères du serveur: UTF-8 Unicode (utf8)

Apache/2.2.15 (CentOS)
Version du client de base de données: libmysql - 5.1.72
Extension PHP: mysqli 
我继续我的研究,它表明AES_解密和UNHEX方法是无罪的。 实际上,如果我直接从phpMyAdmin向表中添加加密值,如下所示:

 INSERT INTO `my_table` (`my_encrypted_column`) VALUES (AES_ENCRYPT('blabla', UNHEX('pass_in_hexa'))
然后,我设法使用上一个SELECT请求正确地检索数据

这意味着问题一定来自我首先插入数据的方式。 为此,我使用了Hibernate和nullSafeSet方法

困扰我的是:如果我保存数据的方式有问题,为什么只能在Windows上工作而不能在Linux上工作

下面是我对nullSafeSet和nullSafeGet的实现

private static final String CIPHER_ALGORITHM = "AES";

// nullSafeSet
protected void noNullSet(PreparedStatement st, Object value, int index, SessionImplementor si) throws SQLException {
    byte[] clearText = ((String) value).getBytes(Charset.forName("UTF-8"));

    try {
        Cipher encryptCipher = Cipher.getInstance(CIPHER_ALGORITHM);
        encryptCipher.init(Cipher.ENCRYPT_MODE, getKey(cle));
        st.setBytes(index, encryptCipher.doFinal(clearText));
    } 
    catch (GeneralSecurityException e) {
        throw new RuntimeException("should never happen", e);
    }
}

@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor si, Object owner) throws HibernateException, SQLException {
    byte[] bytes = rs.getBytes(names[0]);
    try {
        Cipher decryptCipher = Cipher.getInstance(CIPHER_ALGORITHM);
        decryptCipher.init(Cipher.DECRYPT_MODE, getKey(cle));
        if (bytes != null) {
            return new String(decryptCipher.doFinal(bytes), Charset.forName("UTF-8"));
        } 
        else {
            return new String();
        }

    } 
    catch (GeneralSecurityException e) {
        throw new RuntimeException("Mauvaise clé");
    }
}

private static SecretKeySpec getKey(String secretKey) {
    final byte[] finalKey = new byte[16];
    int i = 0;
    for (byte b : secretKey.getBytes()) {
        // XOR
        finalKey[i++ % 16] ^= b;
    }
    return new SecretKeySpec(finalKey, "AES");
}

您知道问题的原因吗?

我认为您的系统之间可能存在链接/填充差异,因为没有明确设置它们。试一试

private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
为了获得您的密码实例,MySql使用了建议的实现

如果您的密码短语长度超过8个字符(字节),mysql将按照建议使用自己的实现从中生成AES 128位密钥 . 当您的密码短语超过8字节时,它可能与Java使用的密钥不同。

检查:

  • 如果这些数据库中有相同的数据。从dev连接到prepod db并检查它是否工作。从prepod连接到您的dev数据库,并检查它是否工作。通过这种方式,您应该缩小问题的范围:db vs environment
  • jvm加密权限。也许您的dev-jvm可以使用强加密,而prepod不能
  • 区分大小写:一些数据库(不确定mysql)将表存储在文件中。windows不区分大小写,linux不区分大小写。我以前也见过这样的问题

您可能有字符集问题。如果您的一个MySQL数据库使用拉丁字符集运行,则插入UTF-8数据将导致数据被置乱

要检查相关表格上的字符集,请在两个系统上运行以下命令:

mysql> show create table foo
| foo | CREATE TABLE `foo` (
  `FLD1` int(11) DEFAULT NULL,
  `FLD2` int(11) DEFAULT NULL,
  `FLD3` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
它将显示该特定表使用的字符集。如果它不是UTF8,那么它将与您的代码不匹配,并且您将遇到数据损坏问题

如果这确实是问题所在,您可以通过运行ALTER语句来更改字符集,如下所示:

ALTER TABLE foo CONVERT TO CHARACTER SET utf8

所以我终于指出了问题所在

在应用程序启动时,我将密钥存储在一个配置对象中。密钥存储为字符串,执行
String cle=new String(key.getEncoded())

这在windows上工作正常,并返回以下键:

*£Ðtôµ•Ã
但在linux上,特殊字符的转换不正确

*��t����

这导致在linux上使用错误的密钥进行加密/解密,因此在执行“选择”时无法使用“正确”的密钥值在MySQL中,
my_table

的架构是什么?my_table有一个my_encrypted_column列,它是longblob类型。来自nullSafeGet和nullSafeSet的一些代码示例将是有用的。@flo我在my中添加了它们post@realUser404检索是通过java代码工作还是也会产生空值?我还没有检查你的建议,我将在本周试用它。我明确说明了AES/ECB/PKCS5Padding,所以现在至少我在两个环境中都得到了相同的结果:当我尝试解密时返回NULL。也许这是另一种算法?至少加上它是可重复的;-)很抱歉,我没有新的猜测,只是简单地回顾一下我应该做的事情:将pre-prod中的key更改为dev上的key-working(使用dev的工作设置:“AES”)。将dev JNDI绑定到pre-prod数据库,并在dev的db上使用设置(可能会将问题减少到pre-prod的java)。将pre-prod的数据复制到dev的db,反之亦然(可能会将问题减少到pre-prod的sql)。我仍然认为这是加密模式/密钥的问题(特别是因为其他答案排除了许多其他问题)。如果有新的事情发生,让我知道,因为我真的很感兴趣的原因。嗯,我的坏,实际上这没有改变任何事情,我只是忘记我尝试在开发环境中使用不同的密钥,所以我认为我不能再解密了,但我只是使用了错误的密钥。因此,最终指定AES/ECB/PKCS5Padding并没有改变任何事情,但我相信这是正常的,因为默认情况下,“AES”应该是AES/ECB/PKCS5Padding,我认为这取决于键(长度)。您在pre-dev上尝试过不同的(较短的)键吗?谢谢,但我的两个数据库都在UTF-8中。那么jdbc.properties中的jdbc URL呢?这在两个系统上都一样吗?我们使用jndi而不是jdbc。我应该寻找什么?即使使用jndi,也必须提供标识数据库的url。此url可以采用影响字符集处理的参数。请参阅以确保您理解我的问题:我无法使用“AES_decrypt”对“linux”数据库中的数据进行解密,但应用程序对其进行了解密。这就是为什么我认为这不是一个数据损坏问题,而是在两个环境中进行加密的方式不同(而代码当然完全相同),所以我尝试了以下方法:在我的开发环境中预编译数据:无法解密。我的Prepod env上的开发数据