Преобразование AES-128-CBC PHP в JAVA

#java #php #encryption

Вопрос:

У меня есть программа шифрования/дешифрования с использованием PHP, и я хочу заменить ее программированием на JAVA.

Я пытался преобразовать, но почему-то результат не был таким же. я искал в Google и на этом форуме эту проблему, но результат не совпадает.

Вот код PHP:

     protected function aes_encode($plain_text) {
    $secret_key = 'TWOFC_ODSACCOUNT';
    $ivBytes = chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0);
    return base64_encode(openssl_encrypt($plain_text, "AES-128-CBC", $secret_key, true, $ivBytes));
}
 

 $plain_text: {"test":"aaaaa"}
Output : /BjE8Fmwcok7rBtD1pdYOO2YkHic7nqXAQQ1/SAsFF8=
 

Вот код JAVA:

 private static final String ALGORITHM = "AES";
private static final byte[] SALT = "TWOFC_ODSACCOUNT".getBytes();

static String getEncrypted(String plainText) {
    if (plainText == null) {
        return null;
    }

    Key salt = getSalt();

    try {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, salt);
        byte[] encodedValue = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encodedValue);
    } catch (Exception e) {
        e.printStackTrace();
    }
    throw new IllegalArgumentException("Failed to encrypt data");
}

static Key getSalt() {
    return new SecretKeySpec(SALT, ALGORITHM);
}
 

  Output : /BjE8Fmwcok7rBtD1pdYOL6iFK9jqAYS86tEAbA/ io=


  
 

Комментарии:

1. Прежде всего, в java для AES-128-CBC вам нужно использовать AES/CBC/PKCS5PADDING алгоритм. Во-вторых, в cipher.init(Cipher.ENCRYPT_MODE, salt); качестве третьего аргумента вам нужно будет передать IV

2. спасибо за ответы, вот код , повторное сообщение неверно. статическая заключительная строка initVector = «0000000000000000»; IvParameterSpec iv = новый IvParameterSpec(initVector.getBytes(«UTF-8»)); SecretKeySpec skeySpec = новый SecretKeySpec(СОЛЬ, «AES»); Шифр cipher = Cipher.getInstance(«AES/CBC/PKCS5PADDING»); шифр.init(Шифр. ENCRYPT_MODE, skeySpec,iv); байт[] Кодированное значение = шифр. doFinal(открытый текст.getBytes()); возвращает Base64.GetEncoder().encodeToString(значение encoded); вывод : Ui8Bdg3SpR6RPcJTY/VkxXOgo65YkeV27kYlc9ctIJ4=

3. Вы должны использовать IvParameterSpec iv = new IvParameterSpec(new byte[16]); . Обратите внимание, что статическая IV, такая как нулевая IV, небезопасна. В PHP-коде OPENSSL_RAW_DATA следует использовать в качестве 4-го параметра вместо true .

Ответ №1:

Как вы можете видеть, зашифрованный текст начинается одинаково. Это обычно означает, что есть проблема с заполнением последнего блока, или что режим неверен, или и то, и другое.

В настоящее время вы используете "AES" в качестве алгоритма. Обычно это значение по умолчанию "AES/ECB/PKCS5Padding" равно . Что вам понадобится, так это "AES/CBC/PKCS5Padding" для нормальной работы CBC. Вы должны предоставить все нулевые IV, чтобы соответствовать PHP-коду.

Возможно, true параметр в PHP / openssl_encrypt приводит к ZERO_PADDING срабатыванию для вызова. В этом случае вам следует вручную создать заполнение нуля. Это означает добавление нулей в открытый текст или последний (частичный) блок открытого текста до тех пор, пока количество байтов открытого текста не станет кратным размеру блока. Вы также должны удалить нулевые байты после расшифровки. И в этом случае вы, конечно, использовали бы "AES/CBC/NoPadding" вместо этого.