Отправка IV с зашифрованным текстом

Я шифрую свое сообщение постоянным секретным ключом и случайным IV, используя AES/CTR/NoPadding на Яве.

Я планирую добавить IV к зашифрованному тексту, а затем Base64 закодировать это.

Теперь есть одна проблема, которая беспокоит меня. Там может быть несколько IV + Шифровать текстовые комбинации, которые могут привести к моему исходному сообщению. Разве это не проблема? Кроме того, безопасно ли отправлять IV как таковой (т.е. добавлять / добавлять к тексту шифра) или есть какая-то процедура, которой я должен следовать?

Я относительно новичок в криптографии, так что извините, если это очень простой вопрос. Я не мог найти удовлетворительного ответа на это.

РЕДАКТИРОВАТЬ:

public static String encrypt(String message) {
    try {
        Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
        byte[] iv = generateRandomIV();
        cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY, new IvParameterSpec(iv));

        byte[] cipherText = cipher.doFinal(message.getBytes("utf-8"));
        return DatatypeConverter.printBase64Binary(concat(iv, cipherText));
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

public static String decrypt(String encryptedMessage) {
    try {
        byte[] bytes = DatatypeConverter.parseBase64Binary(encryptedMessage);
        byte[] iv = getIV(bytes);
        byte[] cipherText = getCipherText(bytes);

        Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY, new IvParameterSpec(iv));

        return new String(cipher.doFinal(cipherText));
    } catch (Exception ex) {
        ex.printStackTrace();
        return encryptedMessage;
    }
}

private static byte[] getIV(byte[] bytes) {
    return Arrays.copyOfRange(bytes, 0, 16);
}

private static byte[] getCipherText(byte[] bytes) {
    return Arrays.copyOfRange(bytes, 16, bytes.length);
}

а потом

public static void main(String[] args) {
    System.out.println(decrypt("wVroKV1UnL2NXiImS83hLKpLLJKk"));
    System.out.println(decrypt("Q0tWAMZDhqMo0LbtEY7lF9D8Dkor"));
}

Оба они производят один и тот же результат - "гуди"

1 ответ

Решение

Может быть несколько текстовых комбинаций IV + Cipher, которые могут привести к моему исходному сообщению. Разве это не проблема?

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

Если он сгенерирует тот же зашифрованный текст, злоумышленник узнает, что было отправлено то же сообщение, что приводит к утечке информации о сообщении. Таким образом, идея IV заключается в том, что он генерирует другой зашифрованный текст, и в большинстве случаев это скорее полезно, чем проблема.

Если это проблема, зависит от вашего протокола. Обратите внимание, что длина зашифрованного текста может по-прежнему отображать информацию о незашифрованном тексте (т. Е. "Утвердительно, сержант", конечно, будет отличаться от шифрования "Нет").

Вам понадобится тег аутентификации / значение MAC для защиты от изменения сообщения. Кроме того, вы можете включить что-то вроде порядкового номера сообщения, чтобы избежать повторных атак.

Однако чем глубже вы идете, тем сложнее становится шифрование. Если вам требуется безопасная транспортировка, то, в конце концов, бесконечно легче использовать TLS или SSH (или любую другую применимую защиту транспортного уровня).

Кроме того, безопасно ли отправлять IV как таковой (т.е. добавлять / добавлять к тексту шифра) или есть какая-то процедура, которой я должен следовать?

Предваряющий его ("prepend" - это не слово во многих словарях, вы также можете использовать "prefix") - это обычный способ обработки IV, да. IV может быть отправлено в любом случае, и это не должно быть конфиденциальным. Однако в случае с CBC он должен быть случайным, а не порядковым номером.

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