Autenticación con un servidor no confiable

1

Anteriormente hice una pregunta relacionada, pero esta vez quiero hacer una versión más amplia:

Para simplificar las cosas, digamos que he desarrollado una aplicación que permite a los usuarios enviar mensajes en una sala de chat y entre ellos (similar a IRC). La naturaleza del mensaje no requiere demasiado secreto, nunca se comparte nada sensible.

Desarrollo un servidor de código abierto y un cliente de código abierto para la aplicación. Los usuarios configurarán sus propios servidores, simplemente proporciono el servidor y los programas cliente.

Quiero que los usuarios tengan cuentas en cada servidor. Lo ideal es que el cliente inicie sesión con un nombre de usuario y una contraseña.

Puedo asumir que el cliente no robará la información de la cuenta porque el usuario la obtuvo de una fuente confiable. El problema es que no se puede confiar en el servidor porque:

  1. El propietario de cada servidor puede hacer modificaciones al código de su servidor.
  2. Pueden ver el contenido de cualquier base de datos.

¿Cómo puedo autenticar a los usuarios?

  1. sin permitir que el propietario del servidor acceda a la contraseña del usuario
  2. sin permitir que el propietario del servidor acceda a un precursor de la contraseña de un usuario (todo lo que no sea la contraseña, pero se puede convertir en la contraseña del usuario o se puede usar para iniciar sesión en otro servidor).
  3. sin depender de una clave precomputada que debe permanecer oculta en el cliente o en el servidor (el código fuente lo revelaría).
  4. idealmente permitiendo una contraseña Editar: Idealmente, la contraseña y el nombre de usuario serían todo lo necesario para iniciar sesión, por lo que al iniciar sesión en diferentes máquinas, el usuario solo necesitará la contraseña y el nombre de usuario.

Los enfoques que tengo en mente:

  1. Respuesta de desafío: envía un desafío, hash con una contraseña y envíala como respuesta. Esto pasa los números de requisito 1 y 3, pero falla el segundo, ya que requiere que el servidor también tenga acceso a la contraseña con hash, que se puede convertir en la contraseña real, o se usa para iniciar sesión en otros servidores (este último es un poco menor, ya que se puede tratar si ocurre). Mi otra pregunta entra en detalles sobre cómo Implementé esta idea para la prueba.

    2: Lista blanca del servidor: Esto se siente un poco como hacer trampa, pero cumple con todos los requisitos al "eliminar" el mayor problema, el hecho de que no se puede confiar en el servidor. Si el cliente intenta conectarse a un servidor que no está en la lista blanca, se emitirá una advertencia con una redacción fuerte (o el acceso a los servidores que no están en la lista blanca podría estar completamente bloqueado). Esto tiene el inconveniente de complicar el proceso de creación de nuevos servidores por parte de los usuarios, y me asigna más responsabilidad que simplemente desarrollar la aplicación (tendría que administrar la lista blanca). Tampoco garantiza necesariamente que se pueda confiar en el servidor, ya que incluso si el propietario no es malicioso, no hay garantía de que tengan la seguridad adecuada en sus sistemas.

pregunta Selali Adobor 10.08.2014 - 08:01
fuente

4 respuestas

1

Cualquier solución implicará una criptografía de clave pública. Cada usuario puede tener un par de claves. La clave secreta se puede cifrar con una contraseña como sugiere @Mark.

Si por alguna razón no es práctico almacenar una clave privada, y el usuario debe poder iniciar sesión con solo el software y una contraseña, la clave privada se puede generar sobre la marcha.

Puede tener una base de datos que contenga lo siguiente para cada usuario:

  1. Datos del usuario

  2. Una sal para la contraseña del usuario

  3. Una sal para la clave pública

  4. Un hash de la clave pública (Hecho con la sal anterior)

Para autenticar:

  1. La contraseña se envía al cliente.

  2. El cliente combina la contraseña salt y la contraseña y usa esta combinación para generar un PRNG.

  3. La salida del PRNG se usa como entrada para cualquier algoritmo de generación de clave privada que elija (RSA o cualquier otro algoritmo de firma).

  4. La clave pública se envía desde el cliente al servidor.

  5. El cliente también debe probar que posee la clave privada correspondiente (esto podría hacerse firmando una identificación de sesión o mediante un protocolo sigma).

  6. Una vez que el servidor sepa que el cliente tiene la clave secreta, valida la clave pública mediante la combinación de la clave pública con el salt almacenado y compara el resultado con el hash almacenado en la base de datos.

Se eligió el orden de los dos últimos pasos para evitar que un atacante que de alguna manera aprendió la clave pública (pero no la clave privada) aprenda si esa clave pública podría usarse para acceder a una cuenta en particular.

No se necesita hash iterado, ya que el algoritmo para generar el par de claves tiende a ser lo suficientemente computacional. A diferencia del hash iterado, el cálculo del par de claves sirve para el propósito secundario de mantener la información secreta bien escondida del servidor.

Si se debe ocultar la existencia de una cuenta de usuario, el servidor puede simular el protocolo cuando se proporciona un nombre de usuario no existente de la siguiente manera:

  • En el primer paso de la autenticación, genere una contraseña pseudoaleatoria y envíela al cliente.

  • Siga el protocolo a través de todos los pasos siguientes sin depender de la base de datos.

  • En el último paso de la autenticación, calcule un hash y descarte el resultado. Rechazar al usuario independientemente del valor del hash.

El desafío restante para ocultar la existencia de una cuenta de usuario es cómo producir una contraseña psuedorandomea que cambia en una frecuencia, lo que es indistinguible de la frecuencia de los cambios de contraseña para un usuario real.

    
respondido por el kasperd 10.08.2014 - 17:18
fuente
2

Parece que desea una criptografía de clave pública similar a la que admite SSH. La idea básica es que el usuario proporcione su clave pública al servidor durante el proceso de creación de la cuenta y luego demuestre su propiedad de la clave privada correspondiente durante el proceso de inicio de sesión.

La clave pública, como su nombre lo indica, ni siquiera es secreta de forma remota, por lo que cumple con el requisito 1, no se puede usar para construir la clave privada, por lo que cumple con 2, se calcula en el momento de la creación de la cuenta, así que cumple con 3, y sí, puede usar una contraseña para proteger la clave privada.

    
respondido por el Mark 10.08.2014 - 08:14
fuente
2

Utilizar certificados. De esa manera, el cliente nunca comparte su clave privada con nadie, incluido el servidor. El servidor solo tiene la clave pública del cliente que no es secreta.

También puede ejecutar una solución de identidad federada o aprovechar una como Google o la de Facebook. Hay opciones de código abierto para esto (como enlace ) Tampoco puede estar completamente seguro de que el cliente no haya sido manipulado, pero en su escenario, de todos modos, no suena como un problema.

    
respondido por el Andy Boura 10.08.2014 - 08:19
fuente
0

Las otras tres respuestas permitirán al usuario iniciar sesión sin que el propietario del servidor pueda ver la contraseña. Sin embargo, en realidad no proporcionan ninguna autenticación . La autenticación es la confirmación de que realmente es usted accediendo a su propia cuenta.

En este escenario, asumimos que el administrador del servidor tiene acceso completo a la base de datos (y ese será el caso en la realidad). Esto significa que el administrador podría cambiar la contraseña de los usuarios a cualquier cosa que le guste, y luego iniciar sesión como ese usuario (y enviar un mensaje a todos sus amigos o leer sus conversaciones privadas o lo que sea).

Creo que la única forma de evitar esto es tenerlo controlado en algún lugar centralizado. Puede implementar sus propias soluciones, o utilizar soluciones ya implementadas. Esto también podría brindarle el beneficio adicional de que una sola cuenta funcione en varios servidores, si le interesa implementarlo de esa manera.

    
respondido por el Chris Murray 19.08.2014 - 17:41
fuente

Lea otras preguntas en las etiquetas