2009-11-23 48 views
14

Estoy seguro de que no hay una sola respuesta a esta pregunta, sino simplemente tratar de descubrir un enfoque general.¿Cómo debo generar un vector de inicialización?

Usando Java 1.4.2, necesito generar una clave y IV para usar en un algoritmo simétrico. Estos valores se compartirán previamente con el destinatario a través de un canal seguro.

La clave que puedo generar con KeyGenerator.keyGenerate(). Pero a menos que me lo pierda, no hay ninguna función para generar un IV aleatorio.

¿Debo hacer algo completamente arbitrario como extraer 16 bytes aleatorios de la memoria? ¿O existe una forma preferida de generar vectores de inicialización suficientemente aleatorios?

Cualquier orientación apreciada.

Respuesta

7

Para algunas implementaciones, la clase SecureRandom le ayudará a cabo mediante la producción de un número real aleatorio:

Muchas implementaciones SecureRandom son en forma de un generador de números pseudo-aleatorios (PRNG), que significa utilice un algoritmo determinista para producir una secuencia pseudoaleatoria a partir de una semilla aleatoria verdadera . Otras implementaciones pueden producir verdaderos números aleatorios, y aun así otros pueden usar una combinación de ambas técnicas .

Tiene dos métodos, getProvider() y getAlgorithm(), que debe darle una cierta información sobre la cual se utiliza la aplicación. Desde this page parece que el generador pseudoaleatorio SHA1PRNG (que está sembrado con datos aleatorios verdaderos) es uno de ellos o incluso el único disponible actualmente.

+1

@schnaader - nit-pick - SHA1PRNG no es un verdadero RNG. Es un PRNG con (según la página a la que se vinculó) una verdadera semilla aleatoria. –

+0

Tienes razón, editó la respuesta. – schnaader

13

Depende del modo en el que utiliza su cifrado. Si está utilizando CBC, los bytes de SecureRandom son los más fáciles, y probablemente los más seguros, siempre y cuando su RNG sea bueno.

La mayoría de los proveedores de Java generarán los parámetros necesarios de forma automática, pero para poder determinar qué se eligió, debe comprender el cifrado y el modo. Por ejemplo, si está utilizando una modalidad que requiere una vía intravenosa, que haría algo como esto:

cipher.init(Cipher.ENCRYPT_MODE, secret); 
IvParameterSpec spec = 
    cipher.getParameters().getParameterSpec(IvParameterSpec.class); 
byte[] iv = spec.getIV(); 

Esto permite al proveedor para elegir un método adecuado para generar la misma IV. Pero si usaras el mismo método en el cifrado usando el modo ECB, fallaría.

El uso de un modo contador obviamente requiere un gran cuidado para evitar la reutilización del contador.

6

Como implican las otras respuestas, use un generador seguro de números aleatorios para crear el IV.

Sin embargo, aparte de eso, no es necesario que envíe el IV a través de un canal seguro; es habitual simplemente anteponerlo al mensaje. Recuerde que es más más importante que use una IV fresca para cada mensaje, que mantener los IV en secreto. Compartir previamente los IV al mismo tiempo que la clave implica que estás reutilizando los IV (malos) o tienes un límite en la cantidad de mensajes que puedes enviar.

1

Si usa la GUI o tiene acceso a las llamadas del sistema al hardware de entrada de datos del usuario (preferido del mouse) puede crear un vector de pares de coordenadas del puntero del mouse mientras el usuario lo mueve. Agréguelos a alguna cadena. Luego usa tu función hash favorita en la cadena para crear IV completamente aleatorio con alta entropía.

Cuestiones relacionadas