Java AES / GCM / NoPadding - ¿Qué me está dando cipher.getIV ()?

Estoy usandoAES/GCM/NoPadding cifrado en Java 8 y me pregunto si mi código tiene una falla de seguridad. Mi código parecetrabajo, ya que cifra y descifra texto, pero algunos detalles no están claros.

Mi pregunta principal es esta:

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

¿Cumple ese IV el requisito de "Para una clave determinada, el IV NO DEBE repetirse". deRFC 4106?

También agradecería cualquier respuesta / visión para mis preguntas relacionadas (ver más abajo), pero esa primera pregunta me molesta más. No sé dónde encontrar el código fuente o la documentación que responde a esto.

Aquí está el código completo, aproximadamente. Pido disculpas en caso de que haya introducido errores al escribir esta publicación:

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);
  }
}

Supongamos que los usuarios descifran mi clave secreta = juego terminado.

Preguntas más detalladas / preguntas relacionadas:

¿El IV devuelto por cipher.getIV () es seguro para que lo use de esta manera?

¿Evita la catástrofe de reutilizar la combinación de teclas IV en el modo Galois / Counter?¿Todavía es seguro cuando tengo varias aplicaciones que ejecutan este código a la vez, y todas muestran mensajes cifrados para los usuarios con los mismos datos src (posiblemente en el mismo milisegundo)?¿De qué está hecho el IV devuelto? ¿Es un contador atómico más un poco de ruido aleatorio?¿Necesito evitarcipher.getIV() y construir un IV yo mismo, con mi propio contador?¿Está implementando el código fuente?cipher.getIV() disponible en línea en algún lugar, suponiendo que estoy usando la extensión Oracle JDK 8 + JCE Unlimited Strength?

¿Ese IV siempre tiene 12 bytes de longitud?

¿La etiqueta de autenticación siempre tiene 16 bytes (128 bits) de longitud?

Con # 2 y # 3, y la falta de relleno, eso significa que mis mensajes cifrados siempre están12 + src.length + 16 bytes de largo? (¿Y entonces puedo aplastarlos de forma segura en una matriz de bytes, para lo cual sé la longitud correcta?)

¿Es seguro para mí mostrar un número ilimitado de encriptaciones de datos src a los usuarios, dados los datos constantes de src que los usuarios conocen?

¿Es seguro para mí mostrar un número ilimitado de encriptaciones de datos src a los usuarios, si los datos src son diferentes cada vez (por ejemplo, incluyendoSystem.currentTimeMillis() o números aleatorios)?

¿Ayudaría si rellenara los datos src con números aleatorios antes del cifrado? ¿Diga 8 bytes aleatorios al frente y atrás, o solo en un extremo? ¿O eso no ayudaría en absoluto / empeoraría mi cifrado?

(Debido a que estas preguntas son sobre el mismo bloque de mi propio código, y están fuertemente relacionadas entre sí, y otras podrían / deberían tener el mismo conjunto de preguntas al implementar la misma funcionalidad, se sintió mal dividir las preguntas en múltiples publicaciones. Puedo volver a publicarlas por separado si eso es más apropiado para el formato de StackOverflow. ¡Avísame!)

Respuestas a la pregunta(1)

Su respuesta a la pregunta