hashing PHP fuerte sin sal

3

La aplicación toma varias entradas (en particular, información personal privada) para producir un hash fijo, pero no adivinable.

Ejemplo simplificado:

$data = $websiteDomain . $myChildSchool . $myPetName . $etc;

for ($i = 0; $i < 1000000; ++$i) {
    $data = hash('sha512', $data, true);
}

$data = str_replace(['/', '+', '='], '', base64_encode($data));

$result = substr($data, 0, $passwordLength);

El objetivo es crear un código publicado públicamente, que genera hashes que luego se usan como contraseñas. Y la parte importante: las contraseñas se pueden recuperar, utilizando el código público y la información personal privada.

Debido a esto, no puedo usar password_hash() porque el resultado es automáticamente Salado por lo que produce diferentes hashes cada vez. No puedo proporcionar manualmente un salt ya que está en desuso (produce una advertencia y es probable que se elimine en futuras versiones de PHP).

Mi principal preocupación es que algunas de las contraseñas se podrían usar en sitios web de mierda, que tienen restricciones de longitud máxima pequeñas y que almacenan las contraseñas de los usuarios como texto sin formato. Por lo tanto, asumo que los atacantes podrían robar los datos de hash del sitio web y usar la fuerza bruta para deducir los datos privados.

En el ejemplo anterior, estoy usando SHA-512 con el estiramiento de las teclas. Sin embargo, SHA no está realmente diseñado para esto, las GPU son increíblemente rápidas y pueden existir, ahora o más adelante, técnicas para sortear todas o parte de las iteraciones.

Entonces, ¿qué tan aceptable es la técnica actual? ¿Podría mejorarse, y si es así, cómo? Lo ideal es que la solución no sea específica de PHP y no requiera bibliotecas externas.

    
pregunta Gras Double 15.11.2016 - 14:11
fuente

1 respuesta

3
  

... los atacantes podrían robar los datos de hash ... y usar la fuerza bruta para deducir los datos privados.

Puede haber algunos problemas prácticos, con respecto a cuánta entropía hay en los datos de entrada

$websiteDomain . $myChildSchool . $myPetName . $etc

Si el atacante conoce parte de esta información, esas partes no tienen entropía. Las partes desconocidas restantes podrían ser forzadas brutalmente por el atacante si los bits de entropía restantes se vuelven demasiado bajos. Debes considerar:

  • Bits de entropía de los datos de entrada después de el atacante ha adquirido la 'fruta de baja altura'.
  • ¿Qué tan sensibles son los datos de entrada restantes, y cuáles son los daños potenciales que se pueden suponer?
  

El propósito es poder recuperar contraseñas ... usando solo mi cerebro y una conexión a Internet. No puedo recordar l33tpa$sw0rd más de una hora, aunque seguramente puedo recordar los nombres de mis padres y demás.

Tenga en cuenta que cada 'pregunta secreta' debe responderse de manera precisa carácter por carácter para que el hash resultante sea consistente. También agregue los bits de entropía para asegurarse de que sean suficientes.

Lea esta descripción de los ventajas y desventajas de cada popular hash de contraseña lenta con notas de implementación. Las mejores opciones son BCrypt, SCrypt y Argon2, siendo la primera la mejor vetada y la última la más nueva en el mercado. Personalmente usaría BCrypt para este proyecto.

  

No puedo usar password_hash() porque el resultado se sala automáticamente para que produzca Hashes diferentes cada vez. No puedo proporcionar manualmente un salt ya que está en desuso (produce una advertencia y es probable que se elimine en futuras versiones de PHP).

Esta función usa BCrypt por defecto, que es una de las buenas opciones. Por supuesto, debería especificar un Salt codificado (no cambiante) (que en esta situación se considera Pepper), y es mejor si puede establecer un Factor de trabajo personalizado . StackOverflow podría ayudarle con esos dos requisitos específicos que se implementarán en PHP.

    
respondido por el George Bailey 15.11.2016 - 15:31
fuente

Lea otras preguntas en las etiquetas