Java AES / GCM / NoPadding - Что мне дает cipher.getIV ()?

я используюAES/GCM/NoPadding шифрование в Java 8, и мне интересно, есть ли в моем коде недостатки безопасности. Мой код кажетсяРаботав том, что он шифрует и дешифрует текст, но некоторые детали неясны.

Мой главный вопрос заключается в следующем:

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = cipher.getIV(); // ?????

Соответствует ли этот IV требованию «Для данного ключа IV НЕ ДОЛЖЕН повторяться». отRFC 4106?

Я также был бы признателен за любые ответы / понимание моих смежных вопросов (см. Ниже), но этот первый вопрос беспокоит меня больше всего. Я не знаю, где найти исходный код или документацию, которая отвечает на это.

Вот полный код, примерно. Я извиняюсь за то, что допустил ошибки при написании этого поста:

class Encryptor {
  Key key;

  Encryptor(byte[] key) {
    if (key.length != 32) throw new IllegalArgumentException();
    this.key = new SecretKeySpec(key, "AES");
  }

  // the output is sent to users
  byte[] encrypt(byte[] src) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] iv = cipher.getIV(); // See question #1
    assert iv.length == 12; // See question #2
    byte[] cipherText = cipher.doFinal(src);
    assert cipherText.length == src.length + 16; // See question #3
    byte[] message = new byte[12 + src.length + 16]; // See question #4
    System.arraycopy(iv, 0, message, 0, 12);
    System.arraycopy(cipherText, 0, message, 12, cipherText.length);
    return message;
  }

  // the input comes from users
  byte[] decrypt(byte[] message) throws Exception {
    if (message.length < 12 + 16) throw new IllegalArgumentException();
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    GCMParameterSpec params = new GCMParameterSpec(128, message, 0, 12);
    cipher.init(Cipher.DECRYPT_MODE, key, params);
    return cipher.doFinal(message, 12, message.length - 12);
  }
}

Предположим, что пользователи взломали мой секретный ключ = игра окончена.

Более подробные вопросы / связанные вопросы:

Безопасно ли использовать таким способом IV, возвращенный функцией cipher.getIV ()?

Избегает ли это катастрофического повторного использования комбинации клавиш IV в режиме Galois / Counter?Все еще безопасно, когда у меня есть несколько приложений, запускающих этот код одновременно, и все они отображают зашифрованные сообщения пользователям с одними и теми же данными SRC (возможно, в одну и ту же миллисекунду)?Из чего сделан возвращенный IV? Это атомный счетчик плюс какой-то случайный шум?Нужно ли избегатьcipher.getIV() и построить IV самостоятельно, со своим счетчиком?Реализует ли исходный кодcipher.getIV() где-нибудь в сети, если предположить, что я использую расширение Oracle JDK 8 + JCE Unlimited Strength?

Это всегда IV длиной 12 байт?

Всегда ли тег аутентификации составляет 16 байтов (128 бит)?

С № 2 и № 3 и отсутствием заполнения, это означает, что мои зашифрованные сообщения всегда12 + src.length + 16 длина байта? (И поэтому я могу смело сжимать их в один байтовый массив, для которого я знаю правильную длину?)

Безопасно ли для меня отображать неограниченное количество шифрований данных src для пользователей, учитывая постоянные данные src, которые пользователи знают?

Безопасно ли для меня отображать неограниченное количество шифрований данных src для пользователей, если данные src каждый раз отличаются (например, включаяSystem.currentTimeMillis() или случайные числа)?

Поможет ли мне заполнить данные src случайными числами перед шифрованием? Скажите 8 случайных байтов впереди и сзади или только на одном конце? Или это вообще не поможет / ухудшит мое шифрование?

(Поскольку все эти вопросы относятся к одному и тому же блоку моего собственного кода, и они тесно связаны друг с другом, а другие могут / должны иметь одинаковый набор вопросов при реализации одинаковых функций, было бы неправильно разделять вопросы на несколько я могу опубликовать их отдельно, если это больше подходит для формата StackOverflow. Дайте мне знать!)

Ответы на вопрос(1)

Ваш ответ на вопрос