Шифрование AES-Rijndael 128 в Java из PHP - PullRequest
0 голосов
/ 08 апреля 2019

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

    function encrypt($data){
$data = "{\"userId\":11,\"email\":\"ssss.bansa11l1989@gmail.com\",\"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\":\"ssss.bansa11l1989@gmail.com\",\"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.

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

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

  • В PHP-коде Zero-Byte-Padding используется , потому что это заполнение 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 устарело и Нулевое байтовое заполнение не является надежным . Если у вас есть выбор изменить отступы, предпочтительнее PKCS7.

0 голосов
/ 08 апреля 2019

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

...