2012-06-14 9 views
19

Como previous discussed, los correos electrónicos de confirmación deben tener un código único (prácticamente) inaplicable, esencialmente un one-time password, en el enlace de confirmación.¿UUID.randomUUID() es adecuado para usar como contraseña de un solo uso?

The UUID.randomUUID() docs dicen:

El UUID se genera utilizando un generador de números aleatorios criptográficamente fuerte seudo .

¿Esto implica que el generador aleatorio UUID en una JVM correctamente implementada es adecuado para su uso como el único OTP (prácticamente) inaplicable?

+2

Usted puede estar interesado en [mi respuesta a otra pregunta,] (http://stackoverflow.com/a/41156/3474) que le dará más seguridad con menos dígitos ... si lo que importa. – erickson

+0

Consulte también la discusión aquí: https://security.stackexchange.com/questions/890/are-guids-safe-for-one-time-tokens –

Respuesta

4

De acuerdo con la UUID spec:

No asuma que los UUID son difíciles de adivinar; no deben usarse como capacidades de seguridad (identificadores cuya mera posesión concede acceso ), por ejemplo. Una fuente de número aleatorio predecible agravará la situación.

Además, los UUID solo tienen 16 caracteres posibles (0 a F). Puede generar una contraseña aleatoria mucho más compacta y explícitamente segura usando SecureRandom (gracias a @erickson).

import java.security.SecureRandom; 
import java.math.BigInteger; 

public final class PasswordGenerator { 
    private SecureRandom random = new SecureRandom(); 

    public String nextPassword() { 
     return new BigInteger(130, random).toString(32); 
    } 
} 
+5

UUID spec! = Implementación de Java. Si bien la especificación no requiere que el UUID sea seguro, la implementación de Java realmente proporciona 122 bits de aleatoriedad segura. Ver también http://stackoverflow.com/a/7532965/47528 – Dan

+0

Aún así recomiendo usar una lib crypto explícitamente. – jchook

+1

Sí, definitivamente ;-) Cuando se trata de seguridad, es mejor ser precavido y explícito. No usaría UUID.randomUUID() para sistemas de grado militar. Pero si la pregunta es "¿Estoy introduciendo un agujero de seguridad usando UUID.randomUUID() para tokens?" Entonces la respuesta es no. – Dan

-1

Creo que esto debería ser adecuado, ya que se genera de forma aleatoria en lugar de desde una entrada específica (es decir, no la está alimentando con un nombre de usuario o algo así), por lo que las llamadas a este código darán resultados diferentes. Indica que es una clave de 128 bits, por lo que es lo suficientemente largo como para ser poco práctico de romper.

¿Va a utilizar esta clave para cifrar un valor, o espera usar esto como la contraseña real? De todos modos, deberá volver a interpretar la clave en un formato que pueda ingresar con un teclado. Por ejemplo, haga una conversión Base64 o Hex, o de alguna manera asigne los valores a alfanuméricos, de lo contrario, el usuario intentará ingresar valores de bytes que no existen en el teclado.

+0

Planeo insertar el código de confirmación en una URL de confirmación que el destinatario del correo electrónico hace clic para completar la confirmación. No debe ser necesaria la intervención del usuario ... – cqcallaw

-1

Es perfecto como una contraseña de tiempo, ya que incluso yo había implementado el mismo para la aplicación en la que estoy trabajando. Además, el enlace que compartió lo dice todo.

0

Si es generado por un CSRNG, entonces es impredecible y, por lo tanto, se puede usar.

Pero el problema al que se dirige es un desperdicio si está enviando correos electrónicos de confirmación sin cifrar: si un atacante tiene los medios para predecir los resultados de RNG, es probable que también puedan interceptar los correos electrónicos.

Los UUID también son cadenas largas (128 bits entonces normalmente Base64 (22 caracteres) o codificados en Base16 (32 caracteres)): piense en qué tan fácil de usar será su sistema. Personalmente, utilizaría un CSRNG para seleccionar 8 caracteres alfanuméricos al azar y devolverlos.

+0

No creo que poder predecir los resultados del RNG implique la capacidad de interceptar el correo electrónico, simplemente implica que el RNG está mal implementado :) Además, no estoy demasiado preocupado por la longitud, porque espero insertar el código en una URL de confirmación que debe visitarse para completar la confirmación. – cqcallaw

0

El punto del código aleatorio para un enlace de confirmación es que el atacante no debería ser capaz de adivinar ni predecir el valor. Como puede ver, para encontrar el código correcto en su enlace de confirmación, un UUID de 128 bits de longitud produce 2^128 códigos diferentes posibles, es decir, 340,282,366,920,938,463,463,374,607,431,768,211,456 códigos posibles para probar. Creo que su enlace de confirmación no es para lanzar un arma nuclear, ¿verdad? Esto es bastante difícil de adivinar para el atacante. Es seguro.

- Actualización -

Si usted no confía en el generador criptográficamente fuerte número aleatorio proporcionado, puede poner algunos parámetros más impredecibles con el código UUID y croquetas de ellos. Por ejemplo,

código = SHA1 (UUID, Proceso PID, ID del hilo, el número de puerto de conexión local, temperatura de la CPU)

Esto hace que sea aún más difícil de predecir.

+2

Solo el número de bits generados no lo hace impredecible. 'java.util.Random' se puede usar para obtener 128 bits de datos, pero eso no significa que sea seguro. –

+2

Hoy en día, las personas atacan para ganar dinero y usted tiene un presupuesto limitado. Nada es irrompible Entonces, ¿qué tan seguro debe ser? El punto de seguridad es: ¿cuánto cuestan romperlo y qué beneficio pueden obtener? Si se trata de un código para el enlace de confirmación de un sitio web común, entonces esto es lo suficientemente seguro.Si este es un código para armas nucleares, entonces no lo diría. Para mí, la definición de seguridad es: el costo de romperla >> La expectativa de ingresos. Cuando cuesta demasiado romperlo, y se pueden obtener pocos ingresos por ruptura, entonces es seguro. –

+0

@LouisWasserman No se puede comparar 'java.util.Random' con' UUID.randomUUID() ' –

13

si usted lee el RFC que define los UUID, y el cual está vinculado a los documentos API, verá que no todos los bits del UUID son aleatorios (la "variante" y la "versión" no son aleatorios) por lo tanto, un UUID de tipo 4 (del tipo que se pretende utilizar), si se implementa correctamente, debe tener 122 bits de (seguro, para esta implementación) información aleatoria, de un tamaño total de 128 bits.

así que sí, funcionará tan bien como un número aleatorio de 122 bits de un generador "seguro". pero un valor más corto puede contener una cantidad suficiente de aleatoriedad y puede ser más fácil para un usuario (tal vez soy la única persona anticuada que todavía lee un correo electrónico en un terminal, pero las URL de confirmación que envuelven líneas son molestas ... .).

+0

Otros proporcionaron respuestas similares, pero esta parecía ser la más completa e informativa. Gracias. – cqcallaw

+7

En realidad, el RFC advierte explícitamente contra el uso de UUID como tokens de seguridad: "No asuma que los UUID son difíciles de adivinar, no deben usarse como capacidades de seguridad (identificadores cuya mera posesión otorga acceso), por ejemplo". Un UUID4 generado ** con un RNG seguro ** será casi imposible de adivinar, pero el estándar explícitamente permite RNG inseguros (!). http://tools.ietf.org/html/rfc4122#section-6 (Disculpas por resucitar un comentario muy antiguo, pero la seguridad es asunto de todos). –

4

Sí, utilizando un java.util.UUID está bien. No hay mucho más que decir.

aquí está mi sugerencia:

  1. enviar al usuario un enlace con una enorme contraseña en él como el argumento URL.
  2. Cuando el usuario hace clic en el enlace, escriba su servidor para que determine si el argumento es correcto o no y el usuario ha iniciado sesión.
  3. Invalida el UUID 24 horas después de su emisión.

Esto requerirá cierto trabajo, pero es necesario si realmente le importa escribir un sistema robusto y seguro.

+1

Su sugerencia es mi intención exacta, excepto que pretendo invalidar el UUID tan pronto como sea posible. a medida que se visita la URL de confirmación y se completa la confirmación. – cqcallaw

Cuestiones relacionadas