0

estoy por crear un proyecto, quiero enfocarme mucho en la seguridad que este vaya a tener, y bueno estoy por desarrollar el inicio de sesión, en lo general yo utilizo el Sha-1 para encriptar las contraseñas, no sé si es lo más seguro, pero hasta ahora es robusto a diferencia de MD5.

Mi pregunta es si estoy bien con el Sha1 en cuestiones de seguridad y encriptación de datos en este caso contraseña, o hay algun otro Hash más seguro que pueda utilizar?

Como les mencionaba quiero enfocarme lo más posible a la seguridad en este sistema, si saben información extra acerca de seguridad o por experiencias, en verdad que me serviria de mucho

Jonathan
  • 500
  • 1
  • 8
  • 19
  • 1
    Ten en cuenta que un cifrado excesivo podría ralentizar la ejecución de la pagina web. Te dejo un enlace que hace referencia al cifrado de las contraseñas con hash. Hay varios ejemplos y en uno de ellos puedes calcular el tiempo de respuesta con el servidor para obtener un cifrado lo más óptimo posible. http://php.net/manual/es/function.password-hash.php – gmarsi Aug 27 '17 at 15:44
  • 1
    Hice una respuesta general de seguridad de sitios web, cualquier duda puedes preguntar y nombrarme en tus comentarios y gustoso te ayudo – Dev 200 Aug 27 '17 at 16:34
  • 1
    El tema de seguridad es muy extenso, tendrás que tener en cuenta muchísimos factores como la configuración correcta del servidor web con HTTPS, qué datos almacenarás en las variables de sesión, etc.. el inicio de sesión es solo la punta del iceberg, sólo el comienzo. – OscarGarcia Aug 27 '17 at 17:11
  • Sha1 es mas seguro que md5. Md5 con fuerza bruta se puede llegar a romper. – ciberelfo Aug 27 '17 at 15:34

2 Answers2

5

Introducción


Siempre nos centramos en colocar seguridad en nuestro sistema, pero el problema no radica en protegerlo externamente, sino internamente.

Incluso aunque coloquemos a Chuck Norris a proteger el sistema, si nuestra Base de datos esta mal diseñada o nuestras sentencias SQL están mal estructuradas, el sistema sera inseguro.


Por eso aqui dejo unas pequeñas recomendaciones:

1) Utiliza PDO en vez de mysql / mysqli, aumentas la seguridad y evitas SQL Injections

Leer:

2) Emplea las sentencias SQL como un lenguaje de programacion (el cual es) y NO como un simple string.

3) Evita usar GET, y usa POST.


Seguridad en las contraseñas:


Una máxima de la programación que considero importante: "Desconfía SIEMPRE del usuario", por esta razón debo evitar darles llaves (usadas en métodos de encriptacion simetricos y asimetricos), o formas de decodificar la información, un usuario normal no haría nada, pero uno con conocimientos o incluso con solo curiosidad podría hacer estragos.

Leer: - Seguridad – Diferencias Entre Cifrado Simétrico, Asimétrico Y Hashing: http://blog.capacityacademy.com/2013/08/16/seguridad-informatica-cifrado-simetrico-asimetrico-hashing/

¿Entonces que debo hacer?:


Usar un hashing:


Los hash o funciones de resumen son algoritmos que consiguen crear a partir de una entrada (ya sea un texto, una contraseña o un archivo, por ejemplo) una salida alfanumérica de longitud normalmente fija que representa un resumen de toda la información que se le ha dado (es decir, a partir de los datos de la entrada crea una cadena que solo puede volverse a crear con esos mismos datos).

El Hashing es una función matemática que no tiene inversa y produce un resultado de longitud fija. A diferencia de la función de cifrado que se utiliza para garantizar la confidencialidad de la información, la función de hashing es utilizada en seguridad para garantizar la integridad de la información.

En PHP tenemos varios metodos, entre ellos md5() y sha1(), pero la documentacion oficial nos dice esto:

Los algoritmos hash como MD5, SHA1 o SHA256 están diseñados para ser muy rápidos y eficientes. Con las técnicas y equipos modernos, es algo trivial extraer por fuerza bruta la salida de estos algoritmos, para determinar los datos de entrada originales.

Dada la velocidad con que los ordenadores actuales pueden "invertir" estos algoritmos hash, muchos profesionales de la seguridad recomiendan encarecidamente no utilizarlas como funciones hash para contraseñas.

Es decir, las pueden revertir:

Ejemplo:

Para mas investigación:

Manual de Contraseñas en PHP: http://php.net/manual/es/faq.passwords.php


¿Ahora bien que método usar?

Sencillo, uno nativo de PHP: password_hash().


Te dejare un link de un polyfill creado para PHP 5.5 de password_hash().

Aunque ya desde PHP 5.5 se trae incluido esta libreria este polyfill tiene un demo que explica como usarlo paso a paso:

PHP 5.5-like password functions for PHP 5.3 and 5.4:

https://github.com/Antnee/phpPasswordHashingLib


¿Como usarlo?:


$hash = password_hash('contraseña', TIPO_DE_ENCRIPTACION);
$hash = password_hash('contraseña', PASSWORD_DEFAULT); //Ejemplo uso DEFAULT

Esta sera la contraseña que guardaremos en la base de datos.

Para verificar:

Obtenemos la contraseña de la BD.

$hash = "qwrqwr25q25q25q25h235h125"; // Ejemplo

Ahora guardamos en una variable el POST de la contraseña introducida para entrar al sistema:

$contraseña = $_POST["password"];

Utilizamos password_verify(), este se encargara de revisar si ese dato corresponde al hash que tenemos guardado.

$hash = "qwrqwr25q25q25q25h235h125"; // Hash en base de datos

$match = password_verify($contraseña, $hash);

PHP guardara el salt usado para verificar la valides de esa contraseña, si tenemos 100 veces el mismo dato, ejemplo "123456", cada hash tendra diferentes valores.

Ahora bien, se recomienda que el campo de contraseña en la base de datos tengo como longitud 255 y ademas sea tipo varchar, pues el hash es una combinación de letras y números.

Si protegemos la base de datos, empleamos sentencias seguras, usamos PDO, y hasheo de datos, el sistema estara internamente 99% seguro.

Dev 200
  • 5,246
  • 5
  • 39
  • 80
  • Estoy investigando ahora, te agradezco mucho toda la información que compartiste, me es de utilidad, aunque aún no termino si es un tema extenso y a la vez muy interesante – Jonathan Aug 27 '17 at 18:30
  • 1
    @Jonathan siii realmente lo es, esa pagina de phpdelusion es muy buena. – Dev 200 Aug 28 '17 at 01:06
  • Veo que la página del gromweb no los puede revertir... Lo que hace es buscar en su base de datos y si existe lo devuelve. –  Jun 25 '21 at 03:57
  • Algo falla en la primera afirmación: "Utiliza PDO en vez de mysql / mysqli, aumentas la seguridad y evitas SQL Injections". ¿De qué manera se aumenta la seguridad y se evita inyección SQL solo por usar PDO? – OscarGarcia Jun 25 '21 at 10:17
1

Un hash es algo así como una huella dactilar. No sirve para cifrar datos ya que ello significaría que debería existir alguna forma de recuperar los datos originales a partir del hash, y eso no es posible.

El algoritmo de hash MD5 reduce un bloque de datos a una huella de 128 bits.

El algoritmo de hash SHA-1 reduce un bloque de datos a una huella de 160 bits.

En un principio ambos deberían ser suficientemente seguros si se usa correctamente junto con una sal, pero el problema está en que en ambos casos se han descubierto maneras de producir "colisiones" sin tener que usar la fuerza brutal sobre el número total de bits.

En la mayoría de algoritmos se necesita una buena cantidad de datos "libres" para poder calcular algo que genere la colisión. En el caso de MD5 se necesitan 128 bytes, por lo que si una contraseña no puede tener 128 caracteres no se puede usar dicho algoritmo para generar una colisión.

En el caso de SHA-1 hay algoritmos que reducen la ruptura a 2^63.

Introducir una sal reduce enormemente la probabilidad de que se obtenga una colisión.

Cuando es evidentemente peligroso usar un HASH que ha sido demostrado vulnerable es para confirmar la integridad de un archivo, por ejemplo un ejecutable, ya que éstos disponen de muchos más bytes para ser modificados para generar la colisión.

En la actualidad se usa SHA-2 con diferentes longitudes de hash: 256, 384 y 512 bits.

Aunque sea más difícil encontrar una colisión para algoritmos de mayor tamaño de bit, siempre es recomendable el uso de una sal.

TODOS LOS ALGORITMOS (probar uno en línea) son vulnerables a ataques de tablas arcoiris. Hay incluso tablas de arcoiris con algunas formas comunes de sal, pero aumenta enormemente el tamaño de la base de datos.

En definitiva, para almacenar el hash de una contraseña de pocos caracteres (por ejemplo 32 o 64 caracteres) no es necesario un algoritmo de hash muy seguro, si no un buen refuerzo con una buena sal.

¿Mi recomendación? Usa SHA-2 con sal o dejar el trabajo a la función de PHP password_hash() que elegirá el algoritmo más seguro y el mejor método de sal hasta ese momento (has de tener en cuenta que en ese caso debes mantener tu versión de PHP al día).

Lo más relevante de la documentación:

PASSWORD_BCRYPT se utiliza para crear nuevos hash de contraseñas empleando el algoritmo CRYPT_BLOWFISH.

Opciones admitidas:

salt - para proporcionar manualmente una sal cuando se realiza el hash de la contraseña. Observe que esto sobrescribirá, previniendo así que se genere una sal automáticamente.

Si se omite, se generará una sal aleatoria mediante password_hash() para cada contraseña con hash. Este es el modo de operación previsto.

OscarGarcia
  • 26,999
  • 3
  • 26
  • 61