2009-10-26 16 views
92

Me doy cuenta de que el OAuth spec no especifica nada sobre el origen de los códigos ConsumerKey, ConsumerSecret, AccessToken, RequestToken, TokenSecret o Verifier, pero tengo curiosidad por saber si existen prácticas recomendadas para crear tokens significativamente seguros (especialmente Token/Combinaciones secretas).¿Mejores prácticas para generar tokens de OAuth?

Tal como lo veo, hay algunos enfoques para la creación de las fichas:

  1. Sólo tiene que utilizar bytes aleatorios, almacenar en el DB asociado al consumidor/usuario
  2. Hash algunos/datos de consumo específico de usuarios, tienda en DB asociado al consumidor/usuario/datos de consumo específico
  3. usuario Cifrar

Ventajas para (1) es la base de datos es la única fuente de la información, que parece el más seguro. Sería más difícil ejecutar un ataque contra que (2) o (3).

Los datos reales hash (2) permitirían volver a generar el token de datos presuntamente ya conocidos. Puede que no proporcione ninguna ventaja a (1) ya que necesitaría almacenar/buscar de todos modos. Más CPU intensiva que (1).

El cifrado de datos reales (3) permitiría descifrar la información. Esto requeriría menos almacenamiento & potencialmente menos búsquedas que (1) & (2), pero potencialmente menos seguro también.

¿Hay otros enfoques/ventajas/desventajas que se deben considerar?

EDIT: otra consideración es que debe haber algún tipo de valor aleatorio en las fichas ya que debe existir la posibilidad de caducar y vuelva a emitir nuevas fichas por lo que no se debe únicamente compuesto por datos reales.

seguir con respecto:

¿Existe una longitud mínima de emergencia para hacer significativamente criptográficamente seguro? Según tengo entendido, Token Secrets más largo crearía firmas más seguras. ¿Es este entendimiento correcto?

¿Existen ventajas al usar una codificación particular sobre otra desde una perspectiva de hash? Por ejemplo, veo muchas API que usan codificaciones hexadecimales (por ejemplo, cadenas GUID). En el algoritmo de firma OAuth, el token se utiliza como una cadena. Con una cadena hexadecimal, el juego de caracteres disponible sería mucho más pequeño (más predecible) que, por ejemplo, con una codificación Base64. Me parece que para dos cadenas de igual longitud, la que tiene el conjunto de caracteres más grande tendría una distribución de hash mejor/más amplia. Esto me parece que mejoraría la seguridad. ¿Es correcta esta suposición?

La especificación OAuth plantea este mismo problema en 11.10 Entropy of Secrets.

+0

¿Por qué el cifrado? ¿No es lo suficientemente bueno? Si solo el hashing es lo suficientemente bueno para la contraseña, ¿no debería ser aún mejor para los tokens de acceso más largos? –

+0

Han pasado 7,5 años desde que hice la pregunta. Honestamente no puedo recordar. – mckamey

+1

Leer de nuevo, hash y cifrado fueron dos enfoques diferentes sugeridos. La encriptación permitiría al servidor obtener información sin una búsqueda de base de datos. Fue una transacción entre muchos. – mckamey

Respuesta

83

OAuth no dice nada sobre token excepto que tiene un secreto asociado. Entonces todos los esquemas que mencionaste funcionarían. Nuestro token evolucionó a medida que los sitios crecen. Estas son las versiones que hemos utilizado antes,

  1. Nuestro primer token es un BLOB cifrado con nombre de usuario, elemento secreto y la caducidad, etc. El problema es que no podemos revocar tokens sin ningún registro en el host.

  2. Así que lo cambiamos para almacenar todo en la base de datos y el token es simplemente un número aleatorio utilizado como la clave de la base de datos. Tiene un índice de nombre de usuario por lo que es fácil enumerar todos los tokens de un usuario y revocarlo.

  3. Tenemos bastantes actividades de piratería. Con número aleatorio, tenemos que ir a la base de datos para saber si el token es válido. Así que volvimos a BLOB encriptado de nuevo. Esta vez, el token solo contiene el valor cifrado de la clave y la caducidad. Entonces podemos detectar tokens inválidos o caducados sin tener que ir a la base de datos.

Algunos detalles de implementación que pueden ayudarle,

  1. Añadir una versión en el testigo de lo que puede cambiar el formato de token sin romper las ya existentes. Todos nuestros tokens tienen primer byte como versión.
  2. Utilice la versión URL-safe de Base64 para codificar el BLOB para que no tenga que lidiar con los problemas de codificación URL, lo que hace que la depuración sea más difícil con la firma OAuth, ya que puede ver una cadena básica codificada triple.
+1

Excelente, gracias. La idea de la versión es buena. Tengo el Base64 compatible con las URL, pero estoy deseando tener una codificación estrictamente alfanumérica para una lectura aún más fácil. – mckamey

+0

¡No había pensado en eso antes, muy interesante! Estaba planeando el almacenamiento de claves de APC para mantener la carga innecesaria fuera del DB antes de leer esto. Todavía no estoy seguro de si esto puede ser mucho más lento que una búsqueda de memoria compartida que realiza APC (al menos en la 2ª, 3ª, etc ... solicitud dentro de un margen de tiempo razonable). – Philzen

-5

¿Qué hay de poner la dirección IP en el token?

Luego, puede en cada solicitud descifrar el token y verificar la dirección IP de la solicitud con la dirección IP del token.

Tal vez ese enfoque sería más seguro contra los ataques generados al azar.

¡Lo mejor!

Editado: Ok, creo que tal vez no estaba claro enaugh. Mi publicación no fue una pregunta. No intentaré encontrar un artículo en Internet donde leo la implementación con dirección IP y estoy de acuerdo en que si pones la dirección IP en el token, los clientes con direcciones IP dinámicas y conexiones móviles tendrán problemas de token.

+1

Creo que es una idea terrible. Nunca debería ser posible reconstruir y descubrir cómo se construye un token de acceso. Puede usar datos de usuario para generar tokens distintos pero siempre combinados con datos aleatorios y datos secretos. Además, podría ser deseable usar el mismo token de acceso en diferentes redes para permitir el roaming (Wifi -> Móvil) – Urizev

+0

Ok, creo que tal vez no estaba claro. –