Шифрование AES-Rijndael 128 на Java из PHP

У меня есть кусок кода на PHP

    function encrypt($data){
$data = "{\"userId\":11,\"email\":\"[email protected]\",\"firstName\":\"Ankit\",\"lastName\":\"Bansal\",\"displayName\":\"banank1989\",\"visitorId\":\"1222222234455\"}";

            $td = mcrypt_module_open('rijndael-128', '', 'cbc', $this->iv);

            mcrypt_generic_init($td, $this->key, $this->iv);
            $encrypted = mcrypt_generic($td, $data);

            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);

            return bin2hex($encrypted);
        }

Теперь, когда я пытаюсь написать тот же код на java, он дает мне другой результат.

public String encrypt(String value) {
        try {

            value = "{\"userId\":11,\"email\":\"[email protected]\",\"firstName\":\"Ankit\",\"lastName\":\"Bansal\",\"displayName\":\"banank1989\",\"visitorId\":\"1222222234455\"}";
            String initVector = "fedcba9876111111";
            String key = "012345678911111";
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(value.getBytes());
            return new String(Base64.encodeBase64(encrypted));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

Теперь проблема в том, что оба кода дают мне разные результаты для одного и того же предоставленного JSON.

Я не могу изменить код PHP, поэтому мне нужно изменить код JAVA.

Является ли то же значение вектора инициализации IV, которое вы используете в java?

Mangesh Sathe 08.04.2019 13:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
213
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете сравнить результат, выполненный вашим кодом, с результатом http://www.maidoupig.cn/encode/aes.

Ответ принят как подходящий

Java и PHP-код отличаются:

  • В PHP-коде используется Заполнение нулями, потому что это заполнение по умолчанию для mcrypt (см. здесь). Напротив, в Java-коде используется PKCS7-Padding (в Java также называемый PKCS5). Чтобы использовать Zero-Byte-Padding в Java-коде, сначала отключите заполнение PKCS7, заменив AES/CBC/PKCS5PADDING на AES/CBC/NoPadding. Во-вторых, реализовать вручную Zero-Byte-Padding, то есть добавить n 0-значений (с 0 <= n < 16) к последовательности байтов сообщения, пока длина не будет соответствовать целому числу, кратному размеру блока (16 байт).
  • В PHP-коде зашифрованные данные возвращаются в виде шестнадцатеричной строки. Напротив, в Java-коде зашифрованные данные возвращаются в кодировке Base64. Чтобы изменить последнее, вы должны преобразовать зашифрованные данные в шестнадцатеричную строку, см., например. Как преобразовать массив байтов в шестнадцатеричную строку в Java?.

С этими изменениями Java- и PHP-код будут давать одинаковый результат, если используется один и тот же ключ и один и тот же IV (кстати, ключ в Java-коде имеет длину 15 байт, что приводит к InvalidKeyException (Invalid AES key length: 15 bytes)).

Обратите внимание на mcrypt устарела и Zero-Byte-Padding ненадежен. Если у вас есть возможность изменить заполнение, PKCS7 предпочтительнее.

Спасибо. Это правильный ответ. Уже исправил, добавив pkcs5 в php-код.

Ankit Bansal 09.04.2019 10:49

Другие вопросы по теме