tipos password_verify password_hash password encriptar encriptada encriptacion ejemplo desencriptar contraseña con argon2 php security passwords hash protection

php - password_hash - password_verify



Hash y sal seguros para las contraseñas de PHP (14)

DESCARGO DE RESPONSABILIDAD : Esta respuesta fue escrita en 2008.

Desde entonces, PHP nos ha proporcionado php.net/manual/en/function.password-hash.php y password_verify y, desde su introducción, son el método de comprobación y comprobación de contraseñas recomendado.

La teoría de la respuesta sigue siendo una buena lectura.

TL; DR

No hacer

  • No limite los caracteres que los usuarios pueden ingresar para las contraseñas. Sólo los idiotas hacen esto.
  • No limites la longitud de una contraseña. Si sus usuarios desean una oración con supercalifragilisticexpialidocious en ella, no evite que la usen.
  • Nunca almacene la contraseña de su usuario en texto plano.
  • Nunca envíe una contraseña por correo electrónico a su usuario, excepto cuando haya perdido la suya, y usted haya enviado una contraseña temporal.
  • Nunca, nunca registre contraseñas de ninguna manera.
  • ¡Nunca hash contraseñas con SHA1 o MD5 o incluso SHA256! Las galletas modernas pueden superar los 60 y 180 mil millones de hashes / segundo (respectivamente).
  • No mezcle bcrypt y con la salida sin formato de hash () , use salida hexadecimal o base64_encode. (Esto se aplica a cualquier entrada que pueda tener un pícaro /0 , lo que puede debilitar seriamente la seguridad).

Dos

  • Usa scrypt cuando puedas; bcrypt si no puedes.
  • Use PBKDF2 si no puede usar bcrypt o scrypt, con hash SHA2.
  • Restablecer las contraseñas de todos cuando la base de datos está en peligro.
  • Implementar una longitud mínima razonable de 8-10 caracteres, además de requerir al menos 1 letra mayúscula, 1 letra minúscula, un número y un símbolo. Esto mejorará la entropía de la contraseña, lo que a su vez hace que sea más difícil de descifrar. (Consulte la sección "¿Qué hace una buena contraseña?" Para un debate).

¿Por qué hash contraseñas de todos modos?

El objetivo de las contraseñas de hash es simple: evitar el acceso malicioso a las cuentas de usuario comprometiendo la base de datos. Por lo tanto, el objetivo del hashing de contraseñas es disuadir a un pirata informático o un cracker al costarle demasiado tiempo o dinero para calcular las contraseñas de texto sin formato. Y el tiempo / costo son los mejores elementos disuasorios en su arsenal.

Otra razón por la que desea un hash bueno y robusto en las cuentas de un usuario es para darle suficiente tiempo para cambiar todas las contraseñas en el sistema. Si su base de datos está comprometida, necesitará tiempo suficiente para bloquear el sistema, por lo menos, si no cambia todas las contraseñas de la base de datos.

Jeremiah Grossman, CTO de Whitehat Security, declaró en su blog después de una recuperación de contraseña reciente que requirió la ruptura de fuerza bruta de su protección de contraseña:

Curiosamente, al vivir esta pesadilla, aprendí MUCHO que no sabía sobre descifrado de contraseñas, almacenamiento y complejidad. He llegado a comprender por qué el almacenamiento de contraseñas es mucho más importante que la complejidad de las contraseñas. Si no sabe cómo se almacena su contraseña, todo lo que realmente puede depender es la complejidad. Esto puede ser de conocimiento común para los profesionales de contraseñas y criptografías, pero para el experto medio en Seguridad de la Información o Web, lo dudo.

(Énfasis mío.)

¿Qué hace una buena contraseña de todos modos?

Entropy . (No es que me suscriba completamente al punto de vista de Randall).

En resumen, la entropía es la cantidad de variación dentro de la contraseña. Cuando una contraseña es solo letras romanas en minúscula, son solo 26 caracteres. Eso no es mucha variación. Las contraseñas alfanuméricas son mejores, con 36 caracteres. Pero permitir mayúsculas y minúsculas, con símbolos, es de aproximadamente 96 caracteres. Eso es mucho mejor que solo letras. Un problema es que, para que nuestras contraseñas sean memorables, insertamos patrones, lo que reduce la entropía. Ups!

La contraseña de la entropía se approximated fácilmente. El uso de la gama completa de caracteres ascii (aproximadamente 96 caracteres tipificables) produce una entropía de 6.6 por carácter, que en 8 caracteres para una contraseña aún es demasiado baja (52.679 bits de entropía) para seguridad futura. Pero la buena noticia es que las contraseñas más largas y las contraseñas con caracteres Unicode realmente aumentan la entropía de una contraseña y hacen que sea más difícil de descifrar.

Hay una discusión más larga sobre la entropía de contraseñas en el sitio Crypto StackExchange . Una buena búsqueda en Google también mostrará muchos resultados.

En los comentarios, hablé con @popnoodles, quien señaló que imponer una política de contraseñas de longitud X con X muchas letras, números, símbolos, etc., puede reducir la entropía al hacer que el esquema de contraseñas sea más predecible. Estoy de acuerdo. La aleatoriedad, tan aleatoriamente como sea posible, es siempre la solución más segura pero menos memorable.

Por lo que he podido decir, hacer la mejor contraseña del mundo es un Catch-22. O bien no es memorable, demasiado predecible, demasiado corto, demasiados caracteres Unicode (difíciles de escribir en un dispositivo Windows / móvil), demasiado largo, etc. Ninguna contraseña es lo suficientemente buena para nuestros propósitos, por lo que debemos protegerlos como si Estaban en Fort Knox.

Mejores prácticas

Bcrypt y Scrypt son las mejores prácticas actuales. scrypt será mejor que bcrypt a tiempo, pero no ha sido adoptado como un estándar por Linux / Unix o por servidores web, y aún no se han publicado revisiones exhaustivas de su algoritmo. Pero aún así, el futuro del algoritmo parece prometedor. Si estás trabajando con Ruby, hay una gema de scrypt que te ayudará, y Node.js ahora tiene su propio paquete de scrypt . Puede usar Scrypt en PHP a través de la extensión Scrypt o la extensión Libsodium (ambas están disponibles en PECL).

Recomiendo leer la documentación de la función crypt si quieres entender cómo usar bcrypt, o encontrarte un good wrapper o usar algo como openwall.com/phpass para una implementación más heredada. Recomiendo un mínimo de 12 rondas de bcrypt, si no 15 a 18.

Cambié de opinión sobre el uso de bcrypt cuando supe que bcrypt solo usa el programa clave de blowfish, con un mecanismo de costo variable. Este último le permite aumentar el costo de forzar una contraseña mediante el aumento del costoso programa clave de Blowfish.

Practicas promedio

Ya casi no puedo imaginar esta situación. openwall.com/phpass admite PHP 3.0.18 a 5.3, por lo que se puede usar en casi todas las instalaciones imaginables, y debe usarse si no está seguro de que su entorno admite bcrypt.

Pero suponga que no puede usar bcrypt o PHPASS en absoluto. ¿Entonces que?

Pruebe una implementación de PDKBF2 con el número máximo de rondas que su entorno / aplicación / percepción del usuario pueda tolerar. El número más bajo que recomendaría es de 2500 rondas. Además, asegúrese de usar hash_hmac() si está disponible para hacer que la operación sea más difícil de reproducir.

Practicas Futuras

Próximamente en PHP 5.5 hay una biblioteca completa de protección de contraseñas que le permite extraer cualquier problema de trabajar con bcrypt. Si bien la mayoría de nosotros estamos atascados con PHP 5.2 y 5.3 en los entornos más comunes, especialmente los hosts compartidos, @ircmaxell ha creado una capa de compatibilidad para la próxima API que es compatible con versiones anteriores de PHP 5.3.7.

Criptografía recapitulación y descargo de responsabilidad

La potencia de cálculo necesaria para realmente descifrar una contraseña con hash no existe. La única forma en que las computadoras pueden "descifrar" una contraseña es recrearla y simular el algoritmo de hash utilizado para asegurarla. La velocidad del hash está relacionada linealmente con su capacidad para ser forzado brutalmente. Peor aún, la mayoría de los algoritmos hash pueden ser paralelizados fácilmente para rendir aún más rápido. Es por esto que los esquemas costosos como bcrypt y scrypt son tan importantes.

No es posible prever todas las amenazas o avenidas de ataque, por lo que debe hacer su mejor esfuerzo para proteger a sus usuarios por adelantado . Si no lo hace, entonces podría pasar por alto el hecho de que fue atacado hasta que sea demasiado tarde ... y usted sea responsable . Para evitar esa situación, actúe paranoico para empezar. Ataca tu propio software (internamente) e intenta robar las credenciales de los usuarios, o modificar las cuentas de otros usuarios o acceder a sus datos. Si no prueba la seguridad de su sistema, no puede culpar a nadie más que a usted mismo.

Por último: no soy criptógrafo. Lo que he dicho es mi opinión, pero creo que se basa en el buen sentido común ... y mucha lectura. Recuerde, sea lo más paranoico posible, haga que las cosas sean lo más difíciles de entrometerse, y luego, si todavía está preocupado, comuníquese con un pirata informático o criptógrafo de sombrero blanco para ver qué dicen sobre su código / sistema.

Actualmente se dice que el MD5 es parcialmente inseguro. Teniendo esto en cuenta, me gustaría saber qué mecanismo utilizar para la protección de contraseña.

Esta pregunta, ¿es el "hash doble" una contraseña menos segura que solo una vez? sugiere que el hashing varias veces puede ser una buena idea, mientras que ¿Cómo implementar la protección de contraseña para archivos individuales? sugiere el uso de sal.

Estoy usando PHP. Quiero un sistema de cifrado de contraseña seguro y rápido. Hashear una contraseña un millón de veces puede ser más seguro, pero también más lento. ¿Cómo lograr un buen equilibrio entre velocidad y seguridad? Además, prefiero que el resultado tenga un número constante de caracteres.

  1. El mecanismo hash debe estar disponible en PHP.
  2. Debe ser seguro
  3. Puede usar sal (en este caso, ¿todas las sales son igualmente buenas? ¿Hay alguna forma de generar buenas sales?)

Además, ¿debería almacenar dos campos en la base de datos (uno con MD5 y otro con SHA, por ejemplo)? ¿Lo haría más seguro o menos seguro?

En caso de que no estuviera lo suficientemente claro, quiero saber qué función (es) de hash usar y cómo elegir un buen sal para tener un mecanismo de protección de contraseña seguro y rápido.

Preguntas relacionadas que no cubren completamente mi pregunta:

¿Cuál es la diferencia entre SHA y MD5 en PHP?
Cifrado de contraseña simple
Métodos seguros de almacenamiento de claves, contraseñas para asp.net
¿Cómo implementarías contraseñas saladas en Tomcat 5.5?


A partir de PHP 5.5, PHP tiene funciones simples y seguras para el hashing y la verificación de contraseñas, php.net/manual/en/function.password-hash.php y password_verify

$password = ''anna''; $hash = password_hash($password, PASSWORD_DEFAULT); $expensiveHash = password_hash($password, PASSWORD_DEFAULT, array(''cost'' => 20)); password_verify(''anna'', $hash); //Returns true password_verify(''anna'', $expensiveHash); //Also returns true password_verify(''elsa'', $hash); //Returns false

Cuando se usa password_hash() , genera un salt al azar y lo incluye en el hash generado (junto con el costo y el algoritmo usado). password_verify() lee ese hash y determina el método de salt y encriptación usado, y lo verifica en contra la contraseña de texto sin formato proporcionada.

Al proporcionar el PASSWORD_DEFAULT indica a PHP que use el algoritmo de hashing predeterminado de la versión instalada de PHP. Exactamente qué algoritmo significa que está destinado a cambiar con el tiempo en futuras versiones, de modo que siempre será uno de los algoritmos más fuertes disponibles.

El aumento del costo (que de manera predeterminada es 10) hace que el hash sea más difícil de forzar la fuerza bruta, pero también significa que generar hashes y verificar las contraseñas contra ellos será más trabajo para la CPU de su servidor.

Tenga en cuenta que aunque el algoritmo de hash predeterminado puede cambiar, los hashes antiguos continuarán verificándose correctamente porque el algoritmo utilizado se almacena en el hash y password_verify() recupera.


Aunque la pregunta ha sido respondida, solo quiero reiterar que las sales utilizadas para el hash deben ser aleatorias y no como una dirección de correo electrónico como se sugiere en la primera respuesta.

Más explicaciones están disponibles en: http://www.pivotalsecurity.com/blog/password-hashing-salt-should-it-be-random/

Recientemente tuve una discusión sobre si los hash de contraseña con sal con bits aleatorios son más seguros que el de sal con sales conocidas o supuestas. Veamos: si el sistema que almacena la contraseña está comprometido, así como el sistema que almacena la sal aleatoria, el atacante tendrá acceso tanto al hash como a la sal, por lo que no importa si la sal es aleatoria o no. El atacante puede generar tablas de arco iris pre-calculadas para romper el hash. Aquí viene la parte interesante: no es tan trivial generar tablas precalculadas. Tomemos el ejemplo del modelo de seguridad WPA. Su contraseña WPA nunca se envía a un punto de acceso inalámbrico. En su lugar, está saturado con su SSID (el nombre de la red, como Linksys, Dlink, etc.). Una muy buena explicación de cómo funciona esto está aquí. Para recuperar la contraseña del hash, deberá conocer la contraseña y el atributo salt (nombre de la red). Church of Wifi ya tiene tablas hash pre-computadas que tienen 1000 SSID principales y aproximadamente 1 millón de contraseñas. El tamaño de todas las tablas es de unos 40 GB. Como puede leer en su sitio, alguien usó 15 arreglos FGPA durante 3 días para generar estas tablas. Suponiendo que la víctima está utilizando el SSID como "a387csf3" y la contraseña como "123456", ¿será descifrado por esas tablas? ¡No! .. no puede. Incluso si la contraseña es débil, las tablas no tienen hashes para SSID a387csf3. Esta es la belleza de tener sal al azar. Disuadirá a los crackers que prosperan en las tablas precalculadas. ¿Puede detener a un hacker determinado? Probablemente no. Pero el uso de sales aleatorias proporciona una capa adicional de defensa. Mientras estamos en este tema, analicemos la ventaja adicional de almacenar sales aleatorias en un sistema separado. Escenario # 1: los hashes de contraseña se almacenan en el sistema X y los valores de sal utilizados para el hashing se almacenan en el sistema Y. Estos valores de sal son adivinables o conocidos (por ejemplo, nombre de usuario) Escenario # 2: los hashes de contraseña se almacenan en el sistema X y los valores de sal utilizados para Los hashing se almacenan en el sistema Y. Estos valores de sal son aleatorios. En caso de que el sistema X haya sido comprometido, como puede adivinar, hay una gran ventaja de usar sal aleatoria en un sistema separado (Escenario # 2). El atacante deberá adivinar los valores de adición para poder descifrar hashes. Si se usa una sal de 32 bits, se requerirán iteraciones de 2 ^ 32 = 4,294,967,296 (aproximadamente 4,2 mil millones) para cada contraseña que se adivine.


Encontré el tema perfecto sobre este tema aquí: https://crackstation.net/hashing-security.htm . Quería que se beneficiara de él. Aquí también hay un código fuente que también ofrece prevención contra ataques basados ​​en el tiempo.

<?php /* * Password hashing with PBKDF2. * Author: havoc AT defuse.ca * www: https://defuse.ca/php-pbkdf2.htm */ // These constants may be changed without breaking existing hashes. define("PBKDF2_HASH_ALGORITHM", "sha256"); define("PBKDF2_ITERATIONS", 1000); define("PBKDF2_SALT_BYTES", 24); define("PBKDF2_HASH_BYTES", 24); define("HASH_SECTIONS", 4); define("HASH_ALGORITHM_INDEX", 0); define("HASH_ITERATION_INDEX", 1); define("HASH_SALT_INDEX", 2); define("HASH_PBKDF2_INDEX", 3); function create_hash($password) { // format: algorithm:iterations:salt:hash $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM)); return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" . $salt . ":" . base64_encode(pbkdf2( PBKDF2_HASH_ALGORITHM, $password, $salt, PBKDF2_ITERATIONS, PBKDF2_HASH_BYTES, true )); } function validate_password($password, $good_hash) { $params = explode(":", $good_hash); if(count($params) < HASH_SECTIONS) return false; $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]); return slow_equals( $pbkdf2, pbkdf2( $params[HASH_ALGORITHM_INDEX], $password, $params[HASH_SALT_INDEX], (int)$params[HASH_ITERATION_INDEX], strlen($pbkdf2), true ) ); } // Compares two strings $a and $b in length-constant time. function slow_equals($a, $b) { $diff = strlen($a) ^ strlen($b); for($i = 0; $i < strlen($a) && $i < strlen($b); $i++) { $diff |= ord($a[$i]) ^ ord($b[$i]); } return $diff === 0; } /* * PBKDF2 key derivation function as defined by RSA''s PKCS #5: https://www.ietf.org/rfc/rfc2898.txt * $algorithm - The hash algorithm to use. Recommended: SHA256 * $password - The password. * $salt - A salt that is unique to the password. * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000. * $key_length - The length of the derived key in bytes. * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise. * Returns: A $key_length-byte key derived from the password and salt. * * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt * * This implementation of PBKDF2 was originally created by https://defuse.ca * With improvements by http://www.variations-of-shadow.com */ function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false) { $algorithm = strtolower($algorithm); if(!in_array($algorithm, hash_algos(), true)) die(''PBKDF2 ERROR: Invalid hash algorithm.''); if($count <= 0 || $key_length <= 0) die(''PBKDF2 ERROR: Invalid parameters.''); $hash_length = strlen(hash($algorithm, "", true)); $block_count = ceil($key_length / $hash_length); $output = ""; for($i = 1; $i <= $block_count; $i++) { // $i encoded as 4 bytes, big endian. $last = $salt . pack("N", $i); // first iteration $last = $xorsum = hash_hmac($algorithm, $last, $password, true); // perform the other $count - 1 iterations for ($j = 1; $j < $count; $j++) { $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true)); } $output .= $xorsum; } if($raw_output) return substr($output, 0, $key_length); else return bin2hex(substr($output, 0, $key_length)); } ?>


Estoy usando openwall.com/phpass que es una clase de PHP de un solo archivo que podría implementarse muy fácilmente en casi todos los proyectos de PHP. Véase también The H.

De forma predeterminada, utilizó el cifrado disponible más fuerte que se implementa en Phpass, que es bcrypt y se remonta a otros encriptados a MD5 para proporcionar compatibilidad con versiones anteriores a marcos como Wordpress.

El hash devuelto podría almacenarse en la base de datos tal como está. El uso de muestra para generar hash es:

$t_hasher = new PasswordHash(8, FALSE); $hash = $t_hasher->HashPassword($password);

Para verificar la contraseña, uno puede usar:

$t_hasher = new PasswordHash(8, FALSE); $check = $t_hasher->CheckPassword($password, $hash);


Google dice que SHA256 está disponible para PHP.

Definitivamente debes usar una sal. Recomiendo usar bytes aleatorios (y no limitarte a caracteres y números). Como de costumbre, cuanto más tiempo elija, más seguro, más lento se volverá. 64 bytes deberían estar bien, supongo.


No almacenaría el hash de contraseña de dos maneras diferentes, porque entonces el sistema es al menos tan débil como el más débil de los algoritmos de hash en uso.


Solo quiero señalar que PHP 5.5 incluye una API de hashing de contraseña que proporciona un envoltorio alrededor de crypt() . Esta API simplifica significativamente la tarea de hash, verificar y volver a usar hashes de contraseña. El autor también ha lanzado un paquete de compatibilidad (en la forma de un solo archivo de contraseña.php que simplemente require usar), para aquellos que usan PHP 5.3.7 y versiones posteriores y desea usarlo ahora mismo.

Por ahora solo es compatible con BCRYPT, pero su objetivo es extenderse fácilmente para incluir otras técnicas de hashing de contraseñas y, dado que la técnica y el costo se almacenan como parte del hash, los cambios en su técnica / costo de hashing preferido no invalidarán los hashes actuales. Automáticamente, utilizará la técnica / costo correcto al validar. También maneja la generación de una sal "segura" si no define explícitamente la suya propia.

La API expone cuatro funciones:

  • password_get_info() - devuelve información sobre el hash dado
  • password_hash() - crea un hash de contraseña
  • password_needs_rehash() : comprueba si el hash dado coincide con las opciones dadas. Útil para verificar si el hash se ajusta a su técnica actual / esquema de costos, lo que le permite repetir si es necesario
  • password_verify() : verifica que una contraseña coincida con un hash

En el momento en que estas funciones aceptan las constantes de contraseña PASSWORD_BCRYPT y PASSWORD_DEFAULT, que son sinónimos en este momento, la diferencia es que PASSWORD_DEFAULT "puede cambiar en nuevas versiones de PHP cuando se admiten algoritmos de hashing más nuevos y más fuertes". El uso de PASSWORD_DEFAULT y password_needs_rehash () en el inicio de sesión (y la repetición si es necesario) debe garantizar que sus hashes sean razonablemente resistentes a los ataques de fuerza bruta con poco o ningún trabajo para usted.

EDIT: Me acabo de dar cuenta de que esto se menciona brevemente en la respuesta de Robert K. Dejaré esta respuesta aquí ya que creo que proporciona un poco más de información sobre cómo funciona y la facilidad de uso que ofrece a aquellos que no conocen la seguridad.


Una respuesta mucho más breve y segura: no escriba su propio mecanismo de contraseña , use un mecanismo probado y comprobado.

La mayoría de los programadores simplemente no tienen la experiencia necesaria para escribir código relacionado con criptografía de forma segura sin introducir vulnerabilidades.

Autoprueba rápida: ¿qué es la extensión de la contraseña y cuántas iteraciones debe usar? Si no sabe la respuesta, debe usar password_hash() , ya que la extensión de la contraseña es ahora una característica crítica de los mecanismos de contraseña debido a que las CPU son mucho más rápidas y el uso de GPU y FPGA para descifrar las contraseñas a tasas de miles de millones de conjeturas por segundo. (con GPUs).

Por ejemplo, puede descifrar todas las contraseñas de Windows de 8 caracteres en 6 horas usando 25 GPU instaladas en 5 computadoras de escritorio. Esto es de fuerza bruta, es decir, enumerar y verificar cada contraseña de Windows de 8 caracteres , incluidos los caracteres especiales, y no es un ataque de diccionario. Eso fue en 2012, a partir de 2018 se podrían usar menos GPU o descifrar más rápido con 25 GPU.

También hay muchos ataques de tabla de arco iris en las contraseñas de Windows que se ejecutan en CPU normales y son muy rápidos. Todo esto se debe a que Windows aún no conserva ni amplía sus contraseñas, incluso en Windows 10. ¡No cometa el mismo error que Microsoft!

Ver también:

  • Excelente respuesta con más información sobre por qué password_hash() o phpass son la mejor manera de hacerlo.
  • buen artículo de blog que proporciona "factores de trabajo" recomendados (número de iteraciones) para los algoritmos principales, incluidos bcrypt, scrypt y PBKDF2.

SHA1 and a salt should suffice (depending, naturally, on whether you are coding something for Fort Knox or a login system for your shopping list) for the foreseeable future. If SHA1 isn''t good enough for you, use SHA256 .

La idea de una sal es desequilibrar los resultados de hash, por así decir. Se sabe, por ejemplo, que el hash MD5 de una cadena vacía es d41d8cd98f00b204e9800998ecf8427e. Entonces, si alguien con suficiente memoria, vería ese hash y sabría que es el hash de una cadena vacía. Pero si la cadena está salada (por ejemplo, con la cadena " MY_PERSONAL_SALT"), el hash para la ''cadena vacía'' (es decir, " MY_PERSONAL_SALT") se convierte aeac2612626724592271634fb14d3ea6, por lo tanto, no es obvio para el retroceso. Lo que estoy tratando de decir, que es mejor usar cualquier sal, de no hacerlo. Por lo tanto, no es demasiado importante saber qué sal usar.

En realidad, hay sitios web que hacen esto : puede alimentar un hash (md5), y escupe un texto plano conocido que genera ese hash en particular. Si obtuviera acceso a una base de datos que almacene hash md5, sería trivial si ingresa el hash para el administrador de dicho servicio e inicie sesión. Sin embargo, si las contraseñas estuvieran incluidas, ese servicio se convertiría ineficaz.

Además, el hash doble se considera generalmente como un método incorrecto, ya que disminuye el espacio resultante. Todos los hashes populares son de longitud fija. Por lo tanto, solo puede tener valores finitos de esta longitud fija y los resultados se vuelven menos variados. Esto podría considerarse como otra forma de salazón, pero no lo recomendaría.


COSAS PARA RECORDAR

Se ha hablado mucho sobre el cifrado de contraseña para PHP, la mayoría de los cuales es un muy buen consejo, pero antes de comenzar el proceso de uso de PHP para el cifrado de contraseña, asegúrese de tener implementado lo siguiente o listo.

SERVIDOR

PUERTOS

No importa qué tan bueno sea su cifrado si no asegura adecuadamente el servidor que ejecuta PHP y DB, todos sus esfuerzos son inútiles. La mayoría de los servidores funcionan de la misma manera, tienen puertos asignados para permitirle acceder de forma remota a través de ftp o shell. Asegúrese de cambiar el puerto predeterminado de la conexión remota que tenga activa. Al no hacer esto, en efecto, hizo que el atacante hiciera un paso menos para acceder a su sistema.

Nombre de usuario

Por todo lo que es bueno en el mundo, no use el nombre de usuario admin, root o algo similar. Además, si está en un sistema basado en Unix NO HAGA acceso al inicio de sesión de la cuenta raíz, siempre debe ser solo sudo.

CONTRASEÑA

Les dices a tus usuarios que hagan buenas contraseñas para evitar ser hackeados, haz lo mismo. ¿Cuál es el punto de pasar por todo el esfuerzo de bloquear la puerta de su casa cuando tiene la puerta trasera completamente abierta?

BASE DE DATOS

SERVIDOR

Lo ideal es que desee su base de datos y su aplicación en servidores separados. Esto no siempre es posible debido al costo, pero permite cierta seguridad ya que el atacante tendrá que seguir dos pasos para acceder completamente al sistema.

USUARIO

Siempre haga que su aplicación tenga su propia cuenta para acceder a la base de datos y solo otorgue los privilegios que necesitará.

Luego, tenga una cuenta de usuario separada para usted que no esté almacenada en ningún lugar del servidor, ni siquiera en la aplicación.

Como siempre NO hagas esta raíz o algo similar.

CONTRASEÑA

Siga las mismas pautas que con todas las buenas contraseñas. Tampoco reutilice la misma contraseña en ninguna cuenta de SERVIDOR o DB en el mismo sistema.

PHP

CONTRASEÑA

NUNCA almacene una contraseña en su base de datos, en lugar de almacenar el hash y la sal única, explicaré por qué más adelante.

HASHING

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Nada hash… De la misma manera y compara los dos hashes. Esto significa que incluso si un atacante obtiene acceso a la base de datos, no sabe cuál es la contraseña real, solo su hash resultante. Lo que significa más seguridad para sus usuarios en el peor escenario posible.

Hay muchas funciones de hash buenas por ahí ( password_hash , hash , etc.) pero es necesario seleccionar un buen algoritmo para que el hash sea efectivo. (bcrypt y otros similares son algoritmos decentes.)

Cuando la clave es la velocidad de hash, más lento es el más resistente a los ataques de Fuerza Bruta.

Uno de los errores más comunes en el hash es que los hashes no son exclusivos de los usuarios. Esto se debe principalmente a que las sales no se generan de forma única.

SALAZÓN

Las contraseñas siempre deben ser saladas antes de hash. Salting agrega una cadena aleatoria a la contraseña para que contraseñas similares no aparezcan iguales en la base de datos. Sin embargo, si la sal no es exclusiva de cada usuario (es decir, utiliza una sal codificada), entonces su sal no tiene valor alguno. Porque una vez que un atacante descubre una contraseña de sal, tiene la sal para todos ellos.

Cuando creas un salt, asegúrate de que sea único para la contraseña con la que se agrega sal, luego almacena tanto el hash como el salt en tu DB. Lo que esto hará es hacerlo para que un atacante tenga que romper individualmente cada sal y hash antes de que puedan acceder. Esto significa mucho más trabajo y tiempo para el atacante.

USUARIOS CREANDO CONTRASEÑAS

Si el usuario está creando una contraseña a través de la interfaz, significa que debe enviarse al servidor. Esto abre un problema de seguridad porque eso significa que la contraseña no cifrada se envía al servidor y, si un atacante puede escuchar y acceder, toda su seguridad en PHP carece de valor. SIEMPRE transmita los datos SEGURAMENTE, esto se hace a través de SSL, pero esté cansado, incluso SSL no es impecable (la falla de Heartbleed de OpenSSL es un ejemplo de esto).

También haga que el usuario cree una contraseña segura, es simple y siempre se debe hacer, el usuario se lo agradecerá al final.

Finalmente, independientemente de las medidas de seguridad que tomes, nada es 100% seguro, mientras más avanzada sea la tecnología para proteger, más avanzados serán los ataques. Pero seguir estos pasos hará que su sitio sea más seguro y mucho menos deseable para los atacantes.

Aquí hay una clase de PHP que crea un hash y salt para una contraseña fácilmente

http://git.io/mSJqpw


I usually use SHA1 and salt with the user ID (or some other user-specific piece of information), and sometimes I additionally use a constant salt (so I have 2 parts to the salt).

SHA1 is now also considered somewhat compromised, but to a far lesser degree than MD5. By using a salt (any salt), you''re preventing the use of a generic rainbow table to attack your hashes (some people have even had success using Google as a sort of rainbow table by searching for the hash). An attacker could conceivably generate a rainbow table using your salt, so that''s why you should include a user-specific salt. That way, they will have to generate a rainbow table for each and every record in your system, not just one for your entire system! With that type of salting, even MD5 is decently secure.


In the end, double-hashing, mathematically, provides no benefit. In practice, however, it is useful for preventing rainbow table-based attacks. In other words, it is of no more benefit than hashing with a salt, which takes far less processor time in your application or on your server.


ok, en el fity necesitamos sal La sal debe ser única, así que vamos a generarla

/** * Generating string * @param $size * @return string */ function Uniwur_string($size){ $text = md5(uniqid(rand(), TRUE)); RETURN substr($text, 0, $size); }

También necesitamos el hash I`m usando sha512, es el mejor y está en PHP

/** * Hashing string * @param $string * @return string */ function hash($string){ return hash(''sha512'', $string); }

Así que ahora podemos usar estas funciones para generar una contraseña segura.

// generating unique password $password = Uniwur_string(20); // or you can add manual password // generating 32 character salt $salt = Uniwur_string(32); // now we can manipulate this informations // hashin salt for safe $hash_salt = hash($salt); // hashing password $hash_psw = hash($password.$hash_salt);

Ahora necesitamos guardar en la base de datos nuestro valor variable $ hash_psw y variable $ sal

y para autorizaremos usaremos los mismos pasos ...

Es la mejor manera de proteger las contraseñas de nuestros clientes ...

Para los últimos 2 pasos, puede usar su propio algoritmo ... pero asegúrese de poder generar esta contraseña con hash en el futuro cuando necesite autorizar al usuario ...