2011-01-25 11 views
6

Estoy desarrollando una aplicación del lado del cliente en C# que se comunicará con un servidor (página php) para credenciales y para algunos servicios críticos. Me pregunto si es peligroso almacenar una contraseña bien hash en la máquina del cliente. Por "bien hash", quiero decir con una semilla aleatoria que usa una conocida función de hashing segura. A los efectos de esta discusión, supongamos que la fuente está disponible gratuitamente (ya que todos los binarios pueden ser de ingeniería inversa).¿Peligroso para almacenar una contraseña bien hash y el método utilizado para hash it a plena vista?

Mi idea era que almacenara el nombre de usuario y la contraseña hash en la computadora del usuario y que este nombre de usuario y hash fueran enviados en texto plano a través de una conexión http no encriptada al servidor para validación. Esto, por supuesto, no evitará que un pirata informático use el hash de nombre de usuario y contraseña de otra persona como propio sin conocer la contraseña de origen (con algunos ajustes de código).

  1. ¿Podría una persona malévola hacer algo con una contraseña hash y el código utilizado para producir el hash? (además de iniciar sesión como otro usuario si obtuvieron esta información)
  2. ¿Qué hacen otras aplicaciones del lado del cliente para evitar que un usuario inicie sesión como otro usuario, si el pirata informático no tiene acceso a la contraseña de origen? (por ejemplo, Steam)
  3. ¿Existe una manera más fácil, económica (tanto de costo como de tiempo) de manejar esto?

Ejemplo de cómo un hacker falsificar credenciales de acceso de otra persona usando mi lógica actual:

  1. usuario se Legit en por primera vez, las credenciales se almacenan
  2. ganancias de hackers el acceso al sistema de archivos , localiza nombre de usuario y contraseña hash
  3. Hacker modifica el código fuente (o utiliza la inyección de código) para enviar el nombre de usuario y la contraseña hash adquiridos en lugar de lo que el programa normalmente haría

El producto que estoy produciendo no va a ser el próximo ebay, facebook o stackexchange, y tiene un bajo presupuesto. No necesito algo de primera categoría, y no me importan los robos ya que estoy planeando usar un modelo de "Paga lo que quieras". Principalmente estoy publicando esto por curiosidad.

+4

"Mi pensamiento era que iba a almacenar el nombre de usuario y contraseña de hash en el ordenador del usuario" - No hagas eso. Como máximo, almacene un token que caduque que no guarde ninguna relación con credenciales que no sean las que se pueden enviar al servidor para reconocer al usuario. –

+1

No es una respuesta, pero la "Criptografía Aplicada" proporciona una buena comprensión de las transacciones seguras. [http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471117099] –

Respuesta

12

En primer lugar, permítanme decir que no es competente para implementar este sistema de forma segura. Yo tampoco. Casi nadie es. Necesita un profesional de seguridad para hacer este trabajo; si intentas transferir tu propia seguridad, te equivocarás y producirás un sistema que los atacantes pueden poner en peligro.

Eso fuera del camino: ha identificado claramente la debilidad de su sistema. Está almacenando una contraseña equivalente; si un atacante obtiene la contraseña equivalente, entonces no importa si tiene la contraseña o no; tienen información suficiente para suplantar al usuario.

La solución es clara. Si te duele cuando haces eso, no hagas eso. No almacene una contraseña equivalente si no se puede confiar en que el sistema que la almacena sea robusto contra ataques.

Si está empeñado en almacenar una contraseña equivalente, guárdela en un almacenamiento al que los atacantes tengan más dificultades para acceder que el sistema de archivos. Si está realmente decidido a guardar cosas peligrosas en nombre del usuario, puede utilizar la API de protección de datos de Windows para almacenarla en un almacenamiento cifrado que se cifra con las credenciales del usuario:

http://msdn.microsoft.com/en-us/library/ms995355.aspx

Pero es mejor no almacenar la contraseña equivalente en primer lugar.

Supongamos que no almacena la contraseña equivalente. No has terminado todavía. Aún necesita considerar los ataques de repetición. Supongamos que el atacante escucha a escondidas sobre el canal no seguro. El usuario ingresa su contraseña, se procesa y se envía al servidor. El espía graba la contraseña hash, y ahora la tiene.

Para resolver esto, el servidor envía un número al azar al cliente. El número nunca más será usado; es de una sola vez. El cliente define la contraseña hash con el número aleatorio y luego cifra el resultado con la clave pública del servidor. El mensaje xor'd encriptado se envía al servidor.

El servidor descifra el hash con su clave privada, lo combina con el número aleatorio que envió anteriormente y determina que el hash descifrado coincide con la contraseña equivalente que está almacenando. Ahora el espía no puede reproducir la contraseña capturada equivalente porque nunca volverán a ver el mismo número aleatorio.

¡Ahora, esto es vulnerable al ataque de hombre en el medio si el cliente no conoce la clave pública del servidor!Si el servidor envía la clave pública al cliente, entonces man-in-the-middle puede interceptar la clave pública del servidor y reemplazarla con su clave pública. Ahora el hombre en el medio puede proporcionar la clave pública y el desafío "aleatorio", y el cliente renunciará a la contraseña equivalente.

Como dije, esto es algo difícil. No intentes hacerlo tú mismo. Obtén un profesional.

+0

O utilice protocolos desarrollados por profesionales, como SSL. +1 – Jacob

+0

¿Realmente vale la pena considerar que se puede observar el sistema de archivos del usuario?Si te preocupa que un programa malicioso robe el hash, ¿no podrían haber instalado un keylogger y aceptar la contraseña cuando ingresaron por primera vez? De hecho, si no ofrece almacenar las credenciales, entonces aumenta la probabilidad de que se expongan a este ataque en el futuro si no lo fueran cuando instalaron el programa por primera vez. – jasonh

+0

@jasonh El programa malicioso que roba el hash puede estar en cualquier enrutador entre el cliente y el sitio web (ninguno de los cuales está controlado por el usuario o el sitio). Además, desde el punto de vista del pirata informático, analizar el tráfico en sentido ascendente puede generar * inicios de sesión múltiples *, mientras que un registrador de pulsaciones de teclas podría arrebatar solo uno. – dbkk

5

Almacenar la contraseña hash en la computadora del usuario los expone a riesgos (considerables); incluso si el acceso a su sitio no es particularmente valioso, muchos usuarios utilizarán el mismo nombre de usuario y contraseña para muchos sitios. Si alguno de ellos usa la misma función hash (como usted dijo, bien conocida) como lo hace, el acceso a esos datos puede dar acceso a un atacante a esos otros sitios web.

Para un método simple y de bajo presupuesto, usaría un sistema simple de desafío/respuesta. Cuando el usuario solicite iniciar sesión, envíeles un número aleatorio. Ingresan su contraseña en un programa del lado del cliente, que la procesa, y usa la contraseña hash como clave para encriptar el número aleatorio, y luego envía ese resultado al servidor. El servidor usa su hash almacenado de la contraseña del usuario para encriptar el mismo número aleatorio. Cuando obtiene el resultado del usuario, compara los dos. El usuario tiene la contraseña correcta si y solo si los dos coinciden.

Si su intención es evitar que el usuario tenga que ingresar la contraseña todo el tiempo, almacene el número aleatorio y el número aleatorio cifrado en su máquina. Siempre que reciban el mismo desafío, pueden enviar la misma respuesta. Cuando/si el desafío cambia, necesitan volver a ingresar la contraseña para encriptar el nuevo desafío.La recuperación de los datos almacenados le da al atacante acceso solo a su sitio, y solo por un período bastante corto de tiempo (y cambiar el desafío antes también es trivial).

Esto evita transmitir la contraseña (incluso en forma hash) en absoluto. La única excepción es durante la configuración inicial, cuando necesita obtener la contraseña hash en el servidor. Para eso, tiene un par de opciones, pero la criptografía PK es probablemente la más obvia: les envía una clave y envían los datos cifrados con esa clave. Si alguien más intercepta los datos, es inútil (a menos que rompan el cifrado, por supuesto).

En cuanto a la forma de generar los números aleatorios, la forma habitual es bastante simple: generar un único realmente de números aleatorios de una fuente como /dev/random en su servidor. Utilice (una versión en hash) como la clave de un algoritmo de cifrado, que ejecuta en el modo contador, es decir, tiene un contador (que no tiene que guardar en secreto) que encripta con esa clave (que mantiene secreto). Cada vez que necesita producir un nuevo desafío, incrementa el contador, lo encripta y envía el resultado.

+0

No compro el argumento sobre otras aplicaciones que usan la misma función hash. Es común que las personas usen la misma contraseña para muchas aplicaciones, a pesar del peligro. Sin embargo, creo que hashing la contraseña antes de almacenarla, JohnMcD. ha protegido adecuadamente estas otras aplicaciones. Otro sitio web debe tomar la * contraseña * original (transmitida a través de un canal seguro), hash ella misma y compararla con un hash almacenado. Si ese sitio web acepta una contraseña * hash * de los usuarios, se implementa incorrectamente. – erickson

+0

@erickson: ¿y tiene la ilusión de que todos (o incluso la mayoría) de los sitios web son particularmente seguros o están bien implementados? –

+0

No, espero que la mayoría de los sitios gasten un mínimo esfuerzo en la autenticación. Es por eso que no creo que esto sea un problema. Para que este ataque funcione, un sitio debería hacer el esfuerzo de averiguar cómo hash (a través de JavaScript?) En el cliente. Eso es extremadamente improbable. Y en el proceso de hacerlo, es probable que vean cuán equivocado está. Es mucho más probable que un sitio haga las cosas de la manera más fácil y envíe la contraseña al servidor. – erickson

2

No me gusta tratar de crear su propio esquema de autenticación. Si utiliza patrones probados por el tiempo, es más probable que los casos límite que no había considerado estén cubiertos. Esto es lo que te sugiero y por qué:

  1. No permita iniciar la sesión con un valor hash en lugar de una contraseña completa. De esta forma, incluso si un atacante adquiere hashes de contraseña almacenados en el servidor, no podrán iniciar sesión con ellos.

  2. Trate de evitar el almacenamiento de contraseñas, incluso contraseñas hash. Si desea un inicio de sesión fácil, la sugerencia de @Mitch es un buen compromiso, pero le sugiero que encripte ese token que expira y tal vez vincule el token que expira con alguna evidencia adicional (por ejemplo, el token se invalida si se envía usando un IP diferente dirección).

  3. Nunca transmita credenciales en texto sin formato. Incluso si las credenciales transmitidas son hash, si se captura el tráfico, es posible un ataque de repetición. SSL no es extremadamente difícil de implementar, y le dará la ventaja adicional de que el cliente puede validar que están hablando con el servidor correcto, lo que ayuda a proteger contra los ataques de hombre en el medio.

  4. Nunca guarde la contraseña de un usuario en el servidor. Guarde un hash salado en su lugar. Asegúrese de que el hash sea un gran valor hash para reducir la probabilidad de que los ataques de fuerza bruta tengan éxito (SHA-256, por ejemplo).

Sé que estás tratando de ir a dar una solución barata, fácil de desarrollar. En lugar de implementar la seguridad de mala calidad para lograr ese objetivo, intente utilizar bibliotecas de autenticación precompiladas y probadas en el tiempo. Esa es una forma de ahorrar tiempo/dinero sin comprometer la calidad.

2

No es peligroso almacenar correctamente contraseñas hash. Es computacionalmente inviable reversar un hash criptográfico y encontrar una contraseña que produzca el hash.

Sin embargo, todo depende de la palabra "adecuada". Primero, la función hash no necesita ser revertida si el usuario elige una contraseña pobre. Una grieta primero prueba una lista de contraseñas comunes, ordenadas por popularidad. Un espacio de contraseñas bastante grande (8 o 9 caracteres) puede ser forzado por fuerza bruta si el algoritmo de hash no utiliza algún tipo de fortalecimiento de claves (miles de iteraciones) para hacerlo computacionalmente costoso. Los diccionarios precalculados son viables si el algoritmo hash no usa una sal.

No estoy seguro si entiendo completamente tu publicación, pero parece que sabes que estás utilizando efectivamente este hash como contraseña. Un hombre en el medio, o alguien que hackee el dispositivo, podrá acceder a su aplicación sin recuperar la contraseña original. El beneficio sería que no tendrían la contraseña "real" del usuario, que es probable que utilicen para muchas otras aplicaciones.

Sería más seguro almacenar la contraseña en el cerebro del usuario y hacer que ingresen cada vez. Sin embargo, si no está utilizando un protocolo seguro como SSL, no parece que valga la pena gastar demasiado esfuerzo en la seguridad en otro lugar. Es razonable hacer que un usuario sea responsable de proteger su propio dispositivo y evitar el robo de la contraseña almacenada. Pero la red sobre la cual lo envían está fuera de su control. Comenzaría con la seguridad del transporte.

2

En segundo lugar todo lo anterior no trata de ser inteligente con el sistema de seguridad. La mejor política es "solo di no" a ese tipo de cosas, en mi opinión.

La buena noticia es que es posible que ni siquiera tenga que molestarse. ¿Ha considerado utilizar una biblioteca de terceros para permitir que sus usuarios inicien sesión a través de OpenID (como parece hacer StackOverflow)? Yo ciertamente nunca he hecho esto por mí mismo antes, pero creo que podría ser una opción robusta y ligera que puede funcionar bien para usted:

http://code.google.com/apis/accounts/docs/OpenID.html

http://wiki.openid.net/w/page/12995176/Libraries

Buena suerte.

+0

Gracias por los enlaces, están resultando bastante útiles –

0

¡Es un paraíso para los hackers!

Cualquier archivo que pertenezca a la seguridad solo debe ser accesible para cualquiera que mantenga el sitio web como una cuestión de política y sin importar los métodos de encriptación utilizados.

De lo contrario, está tentando problemas.

:)

Cuestiones relacionadas