Proteger la contraseña / autenticar durante el tránsito a través de un socket TCP (inseguro) para un juego

4

Background

Estoy diseñando un juego para varios jugadores con un solo servidor que maneja múltiples mundos. Cada jugador inicia sesión en el servidor inicialmente antes de solicitar a qué mundo unirse.

El servidor tiene una dirección IP fija que actualmente es la misma que la dirección IP del sitio. Esto puede cambiar en el futuro si los servidores necesitan ejecutarse en paralelo, sin embargo, a partir de ahora es una suposición segura de que el servidor es, de hecho, el servidor y no un impostor.

Las contraseñas en mi sitio se procesan mediante bcrypt y a salt, y se almacenan en una base de datos MySQL.

Actualmente no tengo un certificado SSL, aunque estoy planeando obtener uno lo antes posible y sin duda antes de que el sitio maneje los detalles de pago, pero es probable que el juego se conecte a través de una conexión TCP abierta, por lo que mi seguridad Las necesidades con respecto a la autenticación de los usuarios del juego deben manejarse manualmente.

Audiencia

El público principal del juego son los adolescentes jóvenes, pero especialmente aquellos que pueden escribir un pequeño código, por lo que puedo esperar que una pequeña cantidad de ellos sean programadores relativamente competentes y un subconjunto más pequeño para poder realizar ingeniería inversa y entrar en Un sistema inseguro.

Mi enfoque actualmente considerado

Pasé un rato pensando en este problema y encontré una solución que parece estar clasificada bajo un algoritmo de "desafío-respuesta", es decir:

  1. El cliente envía un nombre de usuario
  2. El servidor recibe & verifica el nombre de usuario y envía una solicitud de datos de contraseña junto con un token único . Mi idea actual para esto. El token único es generar una cadena aleatoria, MD5, luego anteponer una Único entero incremental para asegurar que tanto el mismo hash es Nunca se envía, y eso no es predecible.
  3. El cliente recibe el token y la contraseña de hashes usando bcrypt con lo conocido sal para obtener el valor en la base de datos del sitio web, y luego agrega la token antes de ejecutarlo de nuevo a través de bcrypt.
  4. El cliente envía este nuevo hash a través del socket
  5. El servidor lee esto, lo verifica y notifica al cliente que está ahora autenticado como el nombre de usuario que enviaron inicialmente.

Aims

Ningún dispositivo, pero el cliente verdadero y el servidor deberían poder encontrar la contraseña, o autenticarse a escondidas para intercambiar datos confidenciales.

Preocupaciones

Tengo un problema particular con este enfoque, ya que ahora los clientes deben conocer la sal secreta que he estado usando en mi sitio web para hacer hash de las contraseñas. Estoy luchando para piense en una razón por la cual esto compromete mi seguridad, pero se siente mal. Supongo que, en teoría, ahora pueden generar previamente las tablas del arco iris y luego, si consiguieran obtener una copia de mi base de datos, habría un tiempo mucho menor entre ellos para obtenerla y descifrar un número decente de contraseñas de usuarios, lo que significa que las cuentas de mis usuarios corren un mayor riesgo ya que tendrán menos advertencias en caso de que ocurra algo.

Fuera de esto, sin embargo, también apreciaría enormemente una evaluación de mi enfoque considerado y cualquier sugerencia o enlace que pueda ser útil para asegurarlo más.

¡Estoy más que feliz de responder cualquier pregunta! Gracias!

    
pregunta Ashley Davies 09.08.2015 - 20:00
fuente

2 respuestas

3

Como sugirió Martin en los comentarios, sugeriría usar TLS . Incluso si su audiencia es adolescentes jóvenes, no es una buena idea divulgar la sal al cliente.

Por ejemplo, ¿qué pasaría si la sal para los hashes está codificada en su aplicación web y un atacante explota una vulnerabilidad para extraer los hashes de contraseña de bcrypt? Si el atacante puede determinar la sal del cliente, entonces el atacante puede comenzar a descifrar los hashes de la contraseña con menos esfuerzo.

Se pueden encontrar algunos buenos recursos sobre por qué no debe rodar su propio cripto here y here .

    
respondido por el infosec 17.08.2015 - 18:21
fuente
0

Estoy de acuerdo en que usar TLS para cifrar todo el intercambio de autenticación sería la mejor solución. Si cree que TLS sería demasiado grande para el alcance que pretende, considere lo siguiente:

  • El uso de la contraseña como un secreto compartido en un esquema de desafío / respuesta no lo acelera de tener que pasar dicho secreto compartido del cliente al servidor la primera vez , cuando el usuario crea una cuenta.

  • Puede usar un cifrado asimétrico simple (el servidor envía una clave pública al cliente, la contraseña del cliente se encripta, la descifra mediante una clave secreta), pero eso no lo salva de los ataques de intermediarios .

Cuando usas TLS:

  • Haga que el servidor y el cliente acuerden con cifrados que sean razonablemente seguros, incluso en el futuro inmediato.

  • Haga que el cliente también realice una autenticación basada en certificados antes de establecer la conexión. No es solo que el servidor se demuestre al cliente que es legítimo, el propio cliente también debe demostrarlo al servidor. Si bien esto no evita que el malware manipule el código en la memoria del cliente y que todavía aparezca en el servidor como legítimo, pondría otra capa de seguridad contra los ataques MITM.

  • Es posible que desee que el certificado del servidor (y el cliente) no sea simplemente autofirmado, sino que esté firmado por un ancla de confianza 'oficial' (como VeriSign) y use el anclaje de CA para protéjase contra los proxies MITM intercambiando los certificados como ya lo hacen los proxies SSL snif-ready.

De esta manera, debería estar razonablemente protegido contra los ataques a los datos en tránsito, y el hecho de que el cliente y el servidor (software y hardware) no sean objeto de esta pregunta.

TL; DR: "Usaré TLS" por sí solo no es el único medio para hacerlo, hay varios escollos que pueden hacer que una conexión cifrada TLS siga siendo vulnerable.

    
respondido por el Anonymous 13.03.2018 - 08:37
fuente

Lea otras preguntas en las etiquetas