repetir numeros numero metodo generar entero arreglo aleatorios aleatorio java encryption aes jce

numeros - ¿Cómo crear una clave segura AES aleatoria en Java?



metodo random java (3)

Mucha buena publicidad en los otros mensajes. Esto es lo que uso:

Key key; SecureRandom rand = new SecureRandom(); KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(256, rand); key = generator.generateKey();

Si necesita otro proveedor de aleatoriedad, que alguna vez hago con fines de prueba, simplemente reemplace rand con

MySecureRandom rand = new MySecureRandom();

¿Cuál es la forma recomendada de generar una clave AES segura y aleatoria en Java, utilizando el estándar JDK?

En otras publicaciones, he encontrado esto, pero usar una SecretKeyFactory podría ser una mejor idea:

KeyGenerator keyGen = KeyGenerator.getInstance("AES"); SecureRandom random = new SecureRandom(); // cryptograph. secure random keyGen.init(random); SecretKey secretKey = keyGen.generateKey();

Sería genial si la respuesta incluyera una explicación de por qué es una buena forma de generar la clave aleatoria. ¡Gracias!


Usar KeyGenerator sería el método preferido. Como Duncan indicó, ciertamente daría el tamaño de la clave durante la inicialización. KeyFactory es un método que debe usarse para claves preexistentes.

OK, entonces vayamos al grano de esto. En principio, las claves AES pueden tener cualquier valor. No hay "claves débiles" como en (3) DES. Tampoco hay bits que tengan un significado específico como en (3) bits de paridad DES. Generar una clave puede ser tan simple como generar una matriz de bytes con valores aleatorios y crear una SecretKeySpec a su alrededor.

Pero el método que está utilizando todavía tiene ventajas: KeyGenerator se creó específicamente para generar claves. Esto significa que el código puede optimizarse para esta generación. Esto podría tener beneficios de eficiencia y seguridad. Podría programarse para evitar un ataque del canal del lado del tiempo que expondría la clave, por ejemplo. Tenga en cuenta que puede que ya sea una buena idea eliminar cualquier byte[] que contenga información clave, ya que puede filtrarse en un archivo de intercambio (sin embargo, este puede ser el caso de todos modos).

Además, como se dijo, no todos los algoritmos usan claves completamente aleatorias. Entonces, usar KeyGenerator facilitaría el cambio a otros algoritmos. Sin embargo, los sistemas de cifrado más modernos solo aceptarán teclas completamente aleatorias; esto se ve como un beneficio importante sobre, por ejemplo, DES.

Finalmente, y en mi caso, la razón más importante, es que el método KeyGenerator es la única forma válida de manejar claves AES dentro de un token seguro (tarjeta inteligente, TPM, token USB o HSM). Si crea el byte[] con SecretKeySpec , la clave debe venir de la memoria. Eso significa que la clave puede colocarse en el token seguro, pero que la clave está expuesta en la memoria independientemente. Normalmente, los tokens seguros solo funcionan con claves que se generan en el token seguro o se inyectan, por ejemplo, mediante una tarjeta inteligente o una ceremonia de tecla. Se puede suministrar un KeyGenerator con un proveedor para que la clave se genere directamente dentro del token seguro.

Como se indica en la respuesta de Duncan : siempre especifique el tamaño de la clave (y cualquier otro parámetro) explícitamente. No confíe en los valores predeterminados del proveedor, ya que esto no aclarará qué está haciendo su aplicación, y cada proveedor puede tener sus propios valores predeterminados.


Usaría su código sugerido, pero con una ligera simplificación:

KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(256); // for example SecretKey secretKey = keyGen.generateKey();

Deje que el proveedor seleccione cómo planea obtener aleatoriedad; no defina algo que puede no ser tan bueno como lo que el proveedor ya ha seleccionado.

Este ejemplo de código asume ( como señala Maarten a continuación ) que ha configurado su archivo java.security para incluir su proveedor preferido en la parte superior de la lista. Si desea especificar manualmente el proveedor, simplemente llame a KeyGenerator.getInstance("AES", "providerName"); .

Para obtener una clave verdaderamente segura, debe utilizar un módulo de seguridad de hardware (HSM) para generar y proteger la clave. Los fabricantes de HSM típicamente suministrarán un proveedor de JCE que hará toda la generación de claves para usted, utilizando el código anterior.