Generando token de autenticación a partir de sesiones de PHP

1

Tengo un sitio PHP tradicional que usa sesiones. He desarrollado una aplicación en tiempo real en nodejs y deseo autenticar a los usuarios aquí en función de su sesión de PHP. El procedimiento sería algo como esto:

  1. La página getAuthToken.php del cliente AJAX
  2. El cliente se conecta al servidor websocket de forma anónima
  3. El cliente envía su token de autenticación
  4. El servidor comprueba el token, autentica al usuario

getAuthToken.php debe generar un token de autenticación para el nombre de usuario de la sesión actual usando alguna clave simétrica (compartida por el servidor websocket) y devolverla.

¿Cuál sería el mejor algoritmo para usar aquí? Tengo poca experiencia con la criptografía y no estoy seguro de dónde proceder.

Un enfoque que viene a la mente sería que SHA-2 incluya el nombre de usuario junto con alguna clave secreta. Luego pasaríamos el nombre de usuario y este hash al servidor websocket que haría lo mismo y compararía los hashes. Incluya una marca de tiempo con el hash para garantizar un token único cada vez.

¿Es seguro el enfoque anterior? ¿Hay un mejor enfoque? No me preocupa nada en el cable, usaremos SSL para todas las comunicaciones; mi única preocupación es la capacidad de suplantar a otros usuarios generando un token falso a través de la inspección de su propio token. El algoritmo debe ser compatible tanto en PHP como en el nodo.

¿Seguro que hay alguna forma estándar de hacer esto?

    
pregunta Abovestand 26.01.2015 - 12:21
fuente

2 respuestas

1

En lugar de solo hash, debe cifrar algunos valores que pueden ser descifrados por sus sistemas PHP y Node.js.

Los datos a incluir podrían ser:

  • Nombre de usuario.
  • Fecha de caducidad del ticket.

Sin embargo, como está encriptando, podría incluir detalles adicionales que necesitaría estar disponibles y estos permanecerían privados para el usuario final.

Estos se cifrarían utilizando AES y una clave simétrica de 256 bits que solo conocen sus aplicaciones PHP y Node.js. Para un vencimiento continuo, debe actualizar la fecha de vencimiento de cada solicitud y emitir un nuevo ticket. Por razones de rendimiento, podría actualizar menos que esto (por ejemplo, una vez que el ticket haya alcanzado su vida media). Este es el método de encriptación que ASP.NET utiliza para sus tickets de autenticación.

Así que tu token podría ser

AES-256(256bit secret key, username + "|" + (date-time + 20 mins))

Después del descifrado, puede verificar que el valor de date-time se encuentre dentro de un rango aceptable (es decir, los próximos 20 minutos); si no, debería registrar esto como un evento de seguridad y esto brindará una protección razonable contra el forzamiento de la fuerza bruta. Si está almacenando esto en una cookie, además de enviarlo a través de WebSockets, puede hacer que la cookie caduque al mismo tiempo (tenga en cuenta que no todos tendrán su reloj configurado correctamente, por lo que es posible que desee agregar algo de margen adicional). para la expiración de la cookie).

Si desea mayor protección, el cifrado no proporciona integridad como se anotó en @GZBK, por lo que es posible que desee garantizar la integridad del valor descifrado. Esto se puede lograr con un HMAC de los datos de hash. Así que tu token se convertiría en:

encrypted_data = AES-256(256bit secret key, username + "|" + (date-time + 20 mins))
ticket = encrypted_data + "|" + HMAC_SHA256(256bit secret key, encrypted_data)

Puedes usar la codificación Base64 para representar los valores dentro de tu ticket.

    
respondido por el SilverlightFox 27.01.2015 - 12:32
fuente
0

El cifrado de los datos no es un requisito: esto es solo seguridad por ofuscación y no proporciona ninguna seguridad complementaria real.

Lo que estás creando es un ticket de sesión: el getAuthToken.php proporciona un ticket al visitante, luego el visitante "muestra" el ticket al servidor websocket para continuar. El websocket deberá realizar dos operaciones aquí:

  • Verifique algunos valores en el ticket (si la marca de tiempo no es demasiado antigua, tiene el privilegio suficiente para acceder a este contenido, si la IP de origen mencionada en el ticket corresponde a la dirección IP de origen de la conexión HTTP actual, etc.) . Estos valores dependen completamente de la aplicación, se pueden almacenar en una sola cookie o en diferentes, aparecen de forma clara, todo esto no importa.
  • Verifique que ninguno de estos valores haya sido alterado, aquí se encuentra toda la seguridad del ticket, y esto se puede hacer usando un algoritmo de hashing bien conocido (por ejemplo, SHA2, pero no intente inventar el suyo o personalizarlo !) tomando todos los datos informativos mencionados anteriormente y una clave secreta como entrada. Esta será la firma que garantiza la autenticidad del boleto.

Para mayor seguridad, si tanto getAuthToken.php como websocket pueden tener acceso a alguna base de datos común (no necesariamente una SQL), puede incluir un identificador aleatorio impredecible en los datos del ticket y almacenarlo en esta base de datos: agregará otra capa de seguridad asegurando que el ticket se haya generado en el lado del servidor y no (incluso muy improbable, siempre y cuando la clave secreta sea lo suficientemente fuerte) forjada en el lado del cliente.

Editar (algunos consejos más):

  • Asegúrese de que la clave sea lo suficientemente larga para no debilitar el hash (al menos siempre que el tamaño final del hash, debe generarlo usando una computadora, ya que el cerebro humano suele ser bastante pobre en términos de entropía, posiblemente cambie algunos carácter posterior si realmente no confías en el PRNG de tu computadora),
  • Algunos idiomas proporcionan una versión "hmac" de funciones de hash específicas para este propósito (tomando la clave como un argumento separado para una mejor seguridad criptográfica)
  • Incluso si no está marcada en una base de datos, puede incluir una ID de "sesión" aleatoria en sus datos de hash: agregará algo de ruido que evitaría cualquier posible análisis estadístico o de tiempo ya que el pirata informático no podrá predecir la cadena exacta que será calculada por el servidor,
  • Siéntase libre de cambiar la clave secreta de vez en cuando, dependiendo de su arquitectura, puede ser una tarea bastante sencilla y de bajo impacto que anulará cualquier trabajo en curso para forzar su clave (la frecuencia depende completamente de su nivel de paranoia) )
respondido por el WhiteWinterWolf 26.01.2015 - 19:25
fuente

Lea otras preguntas en las etiquetas