password encriptar encriptación encriptacion desencriptar contraseñas contraseña and passwords client-side hash

passwords - encriptar - hash password php mysql



Vale la pena contraseñas hash en el lado del cliente (11)

Cuando quiero poner un sistema de inicio de sesión en su lugar, siempre comparo el MD5 de la contraseña dada con su valor en la tabla de usuarios en el lado del servidor.

Sin embargo, un amigo mío me dijo que una contraseña "clara" podría ser olfateada por un software de red.

Entonces mi pregunta es: ¿es una buena idea poner la contraseña en el lado del cliente? ¿Es mejor que hash en el lado del servidor?


Básicamente, tu amigo tiene razón. Pero simplemente cifrar la contraseña en el lado del cliente solo es mejor que enviarla como texto sin formato al servidor. Alguien que puede escuchar sus contraseñas de texto sin formato también es capaz de escuchar las contraseñas hash, y usar estos hashes capturados para autenticarse contra su servidor.

Para este caso, los protocolos de autenticación más seguros normalmente pasan por varios niveles para asegurarse de que dicho ataque de repetición no puede funcionar, generalmente, al permitir que el cliente seleccione un grupo de bits aleatorios, que son hash junto con la contraseña. , y también enviado en el claro para el servidor.

En el servidor:

  • generar algunos bits de azar
  • envíe estos bits (en texto claro) al cliente

En el cliente:

  • generar algunos bits aleatorios
  • concatenar la contraseña, los bits aleatorios del servidor y los bits aleatorios del cliente
  • generar hash de los anteriores
  • enviar datos aleatorios (en texto claro) y hash al servidor

Como el servidor conoce su propia información aleatoria, así como los bits aleatorios del cliente (los obtuvo como texto claro), puede realizar esencialmente la misma transformación. Este protocolo asegura que nadie que esté escuchando en esta conversación pueda usar la información más tarde para autenticarse falsamente usando la información grabada (a menos que se use un algoritmo muy débil ...), siempre y cuando ambas partes generen diferentes "bits de ruido" cada vez, el apretón de manos se realiza.

Editar Todo esto es propenso a errores y tedioso y algo difícil de corregir (leer: seguro). Si alguna vez es posible, considere usar implementaciones de protocolos de autenticación ya escritas por personas conocedoras (¡a diferencia de mí! Lo anterior es solo de la memoria de un libro que leí hace algún tiempo). Realmente no desea escribir esto usted mismo normalmente.


Considera esto:-

El cliente envía una solicitud al servidor "Tengo una contraseña para validar".

El servidor envía al cliente una cadena aleatoria única de una sola vez. R $

El cliente incorpora la contraseña del usuario en esta cadena (en función de las reglas (variables) que desee aplicar).

El cliente envía la cadena al servidor y, si la contraseña es correcta, el servidor registra al usuario.

Si el servidor recibe otra solicitud de inicio de sesión con R $, el usuario se desconecta y la cuenta se congela en espera de una investigación.

Obviamente, se tomarán todas las demás precauciones de seguridad (normales).



En primer lugar, esto NO mejora la seguridad de su aplicación (suponiendo que sea una aplicación web).

Use SSL (o en realidad TLS, que comúnmente se llama SSL), no es realmente costoso (mida el tiempo que está usando para encontrar formas de evitarlo y multiplíquelo con un salario mínimo, comprar un certificado gana casi siempre).

El porqué de esto es simple. TLS resuelve un problema (cuando se usa con certificados comprados, no autofirmados) que es bastante grande en criptografía: ¿cómo sé que el servidor con el que estoy hablando es el servidor con el que creo que estoy hablando? Los certificados TLS son una forma de decir: "Yo, la autoridad de certificación, en la que confía su navegador, certifica que el sitio web en [url] tiene esta clave pública, con la clave privada correspondiente, que (clave privada) solo el servidor conoce, mira Firmé mi firma en todo el documento, si alguien lo alteró puede ver ".

Sin TLS, cualquier encriptación no tiene sentido, porque si me siento a tu lado en una cafetería, puedo hacer que tu laptop / teléfono inteligente piense que soy el servidor y MiTM (Hombre en el Medio). Con TLS, su computadora portátil / teléfono inteligente gritará "CONEXIÓN INESTIMABLE", porque no tengo un certificado firmado por la autoridad de certificación que coincida con su sitio. (Cifrado vs. Autenticación).

Descargo de responsabilidad: los usuarios tienden a hacer clic a la derecha a través de estas advertencias: "¿Conexión que no es de confianza? ¿Qué? ¡Solo quiero mis imágenes de gatitos! Agregar excepción Haga clic en Confirmar ¡ Haga clic en YAY! Gatitos!"

Sin embargo, si realmente no desea comprar un certificado, aún DEBE implementar el hashing de JavaScript del lado del cliente (y use la biblioteca de standford (SJCL) para eso, NUNCA IMPLEMENTE CRYPTO YOURSELF ).

¿Por qué? Reutilización de contraseña! Puedo robar tu cookie de sesión (lo que me permite fingir que soy tu servidor) sin HTTPS fácilmente (mira fireresheep). Sin embargo, si agrega un javascript a su página de inicio de sesión que, antes de enviar, comprueba su contraseña (use SHA256, o mejor aún, use SHA256, envíele una clave pública que haya generado y luego encripte la contraseña con esa, no puede usar una sal con esto), y luego envía la contraseña hash / encriptada al servidor. REPITA el hash en su servidor con un salt y compárelo con lo que está almacenado en su base de datos (almacene la contraseña de esta manera:

(SHA256(SHA256(password)+salt))

(guarde la sal como texto sin formato en la base de datos también)). Y envía tu contraseña de esta manera:

RSA_With_Public_Key(SHA256(password))

y comprueba tu contraseña de esta manera:

if SHA256(RSA_With_Private_Key(SHA256(sent_password))+salt_for_username) == stored_pass: login = ok

Porque, si alguien está olfateando a su cliente, podrán iniciar sesión como su cliente (secuestro de sesión) pero NUNCA verán la contraseña de texto plano (a menos que alteren su javascript, sin embargo, un hacker de Starbucks probablemente no sepa cómo / estar interesado en esto.) De modo que obtendrán acceso a su aplicación web, pero no a su correo electrónico / facebook / etc. (para lo cual sus usuarios probablemente usarán la misma contraseña). (La dirección de correo electrónico será su nombre de usuario o se encontrará en su perfil / configuración en su aplicación web).


En realidad, no estoy de acuerdo con que el hash del lado del cliente sea más seguro en este caso. Creo que es menos seguro.

El objetivo de almacenar un hash de la contraseña en su base de datos en lugar de la contraseña real (o incluso una contraseña encriptada) es que matemáticamente es imposible obtener la contraseña original de un hash (aunque teóricamente es posible obtener un colisionamiento entrada hash, cuya dificultad depende de la seguridad del algoritmo hashing). El posible vector de ataque aquí es que si un atacante potencial de alguna manera comprometía su base de datos de almacenamiento de contraseñas, aún no podría obtener las contraseñas originales de sus usuarios.

Si su mecanismo de autenticación envía un hash de la contraseña, entonces en este escenario de violación de seguridad, el atacante no necesita saber la contraseña real: solo envía el hash que tienen y listo, tienen acceso a una cuenta de usuario en particular, y por extensión, todo tu sistema. Esto en primer lugar derrota por completo el punto de almacenamiento de una contraseña hash.

La forma más segura de hacerlo es enviar al cliente una clave pública de una sola vez para que cifre la contraseña, y luego descifrarla y volver a codificarla en el servidor.

Por cierto, este tipo de pregunta probablemente obtendrá más respuestas expertas en Security StackExchange.


He estado trabajando mucho en esto recientemente, IRL hay dos problemas con el cifrado hash / simétrico del lado del cliente que realmente mata la idea: 1. Tienes que devolver la sal al servidor DE ALGUNA MANERA ... y encriptar en el lado del cliente, necesitaría una contraseña ... lo que frustraría el propósito. 2. Expone su implementación hash (no es un gran trato ya que la mayoría de los sitios usan uno de 3 o 4 alísos hash) lo que hace que el ataque sea más fácil (solo necesita probar uno en lugar de n).

Lo que eventualmente fui fue una encriptación asimétrica en el cliente usando OpenPGP.js o similar ... Esto depende de una clave importada o generada del lado del cliente en el cliente y del servidor que la envía. Solo la clave pública del cliente puede enviarse nuevamente al servidor. Esto protege contra los ataques MIM y es tan seguro como el dispositivo (actualmente almaceno la clave privada del cliente por defecto en localStore, es una demostración).

La principal ventaja de esto es que nunca tengo que tener los datos de los usuarios almacenados / incluso en la memoria desencriptada en mi servidor / almacén de datos (y la clave privada de mi servidor está físicamente separada)

La base de esto fue proporcionar a las personas una forma de comunicarse de forma segura donde HTTPS estaba restringido (p. Ej., Irán / Corea del Norte atc ...) y también solo como un experimento divertido.

Estoy lejos de ser el primero en pensar en esto, http://www.mailvelope.com/ usa esto


Lo más probable es que no se preocupe por esto, ya que Dirk menciona incluso si tiene las contraseñas que un usuario malintencionado podría tener en una red y ve que se envía el hash, y podría simplemente enviar el mismo hash.

Es ligeramente mejor, ya que evita que el usuario malintencionado sepa cuál es la contraseña, pero dado que aún puede iniciar sesión (o posiblemente reconstruir la contraseña original ), no es tan útil.

En general, si le preocupa la seguridad de las contraseñas y datos de su usuario (¡y debería estarlo!), Querrá usar un servidor SSL seguro. Si esto no es una preocupación para usted por la razón que sea, es mejor que no se moleste con hashing; es solo seguridad a través de la oscuridad .

Edición de agosto de 2014: Google está presionando cada vez más a los sitios web para que cambien a HTTPS en todas partes , porque proteger la comunicación en sí es la única forma de evitar los ataques de detección de redes. Los intentos de ofuscar los datos transmitidos solo obstaculizarán, no detendrán, a un atacante dedicado, y pueden dar a los desarrolladores una falsa sensación de seguridad peligrosa.



Recientemente, tanto GitHub como Twitter anunciaron que las contraseñas se almacenaban en registros internos. He tenido esto suceder inadvertidamente en informes de errores y otros registros que encontraron su camino en splunk, etc. Para Twitter, si la contraseña de Trump estaba ahí log, podría ser un gran problema para un administrador "ver", para otros sitios probablemente no tan gran cosa, ya que los administradores no tendrían mucho uso para eso. Independientemente de los administradores, no nos gusta ver las contraseñas, ¿verdad?

Entonces, la pregunta es si el hash debe ocurrir en el lado del cliente para la seguridad, pero ¿cómo podemos proteger la contraseña antes de que finalmente se procese y se compare por el lado del servidor para que no se logre de alguna manera?

El cifrado no es una mala idea porque los desarrolladores, al menos, tienen que saltar algunos aros, y si encuentra que las contraseñas se ingresaron en los registros, puede cambiar la clave de cifrado, destruir el original y esos datos se vuelven inútiles. Mejor aún rotar las llaves todas las noches y podría reducir las ventanas en gran medida.

También puede hash un hash en su registro de usuario. Las contraseñas filtradas serían contraseñas de texto sin formato. El servidor almacenaría una versión hash del hash. Claro que el hash se convierte en la contraseña, pero a menos que tengas una memoria fotográfica no recordarás un bicrpt de 60 caracteres. Salt con el nombre de usuario. Si puede recopilar algo sobre el usuario durante el proceso de inicio de sesión (sin exponer que exista el registro del usuario), también puede crear un hash más robusto que no se pueda compartir entre los sitios. Ningún hombre en el medio sería capaz de cortar y pegar el hash capturado entre los sitios.

Combine con una cookie que no se envía de vuelta al servidor y es posible que esté en algo. En la primera solicitud envíe una cookie al cliente con una clave, luego asegúrese de que la cookie no vuelva al servicio de inicio de sesión, por lo que hay pocas posibilidades de que se registre. Almacene la clave en una tienda de sesiones, y luego elimínela justo después de iniciar sesión o cuando la sesión haya expirado ... esto requiere que los JWT le digan estado, pero tal vez solo use un servicio de menequios.

Entonces, en el futuro, un administrador encuentra una de estas contraseñas cifradas y hash en Splunk o una herramienta de informe de errores. Debería ser inútil para ellos, ya que no pueden encontrar la clave de cifrado, e incluso si lo hicieron, entonces tienen que usar la fuerza bruta de un hash. Además, el usuario final no envió nada de texto plano a lo largo de la línea, por lo que cualquier hombre en el medio lo tiene más difícil y no puedes saltar a otro sitio e iniciar sesión.


Si alguien puede ver los datos dentro y fuera de su conexión, la autenticación no lo salvará. En su lugar, haría lo siguiente por cosas súper secretas.

Las contraseñas están precedidas por el lado del cliente antes de ser enviadas al servidor. (El servidor almacena otro valor hash y salado de ese hash enviado desde el navegador).

Entonces, un ataque de intermediario podría permitirles enviar el mismo valor hash para iniciar sesión como ellos, pero no se conocería la contraseña de los usuarios. Esto les impediría probar otros servicios con las mismas credenciales para iniciar sesión en otro lugar.

Los datos de los usuarios también están encriptados en el lado del navegador.

Ah, entonces un ataque de intermediario obtendría los datos cifrados, pero no sería capaz de descifrarlos sin la contraseña real utilizada para iniciar sesión. (contraseña de los usuarios almacenada en el DOM en el navegador cuando iniciaron sesión). Entonces, el usuario real vería los contenidos descifrados pero el intermediario no podría. Esto también significa que cualquier NSA u otra agencia no podrá solicitarle a usted / compañía / proveedor de servicios de hosting que descifren esta información ya que sería imposible que lo hagan también.

Algunos pequeños ejemplos de ambos métodos están en mi blog http://glynrob.com/javascript/client-side-hashing-and-encryption/


Uno puede considerar los sitios como amazon.com y linkedin.com. Estos sitios no hacen hash en el lado del cliente. (Como en abril de 2018).