Anidando bcrypt + PHPass para mejorar la seguridad del almacenamiento de contraseñas en software heredado?

3

Me han asignado la tarea de mejorar la seguridad del almacenamiento de contraseña de un sitio que actualmente utiliza PHPass de Openwall . Todos los hashes se convertirán a la vez, i. mi. no queremos esperar a que el usuario inicie sesión para volver a aplicar su contraseña.

Para lograr esto, pensé que podríamos usar bcrypt sobre los hashes PHPass existentes , de esta manera: bcrypt(phpass(password))

Pero necesitamos un paso intermedio importante: al igual que bcrypt, PHPass tiene su propia sal incrustada en el hash, así que tenemos que "cargar" esa sal en bcrypt si queremos que la operación sea repetible al verificar los hashes.

Afortunadamente, el tamaño de la sal de PHPass es más pequeño (6 bytes) que el de bcrypt (16 bytes), por lo que podemos "compartir" los primeros 6 bytes de la sal y agregar 10 bytes aleatorios adicionales para bcrypt.

Imagina algo como esto en pseudo-PHP:

$password = 'somestring123';

$hash = phpass($password)

// $hash is now '$H$9Uvsrbh2Wxo3SebfGb4xVtODMmD2K70',
// where 'Uvsrbh2W' is an encoded, random salt of 6 'raw' bytes

$raw_salt = decode(substr($hash, 4, 8));

$hash = bcrypt_with_custom_salt($hash, $raw_salt . random_bytes(10));

// $hash is now '$2y$12$Uvsrbh2WzN9HrapVpnmu2OYOdJ2jnjHt2LTwIYQPJe.BUJQKezKuO'
// whose salt uses the first 6 bytes we had in phpass,
// so that we can repeat the process when veryfing the password
// since we have all the salts available in only one hash

Salvo cualquier error de implementación y asumiendo que las fuentes aleatorias son criptográficamente seguras, ¿es esta una forma teóricamente segura de usar bcrypt en un contexto heredado? Desde mi entendimiento, el resultado debería ser tan seguro ( Si no es más ...? ) solo estoy haciendo bcrypt(password) , pero no soy un experto y es posible que me falten algunos detalles oscuros.

    
pregunta MM. 23.03.2017 - 13:49
fuente

4 respuestas

1

El ajuste por una sola vez de PHPass en bcrypt debería proporcionar una importante resistencia adicional de fuerza bruta sin conexión. Como comenté anteriormente, usando factores de trabajo predeterminados, el hashcat puede descifrar PHPass fallback md5crypt-style PHPass unas 500 veces más rápido que bcrypt.

La reutilización de la sal interna de PHPass para usar con el bcrypt externo parece razonable. (¡Ciertamente parece mejor que una sal estática!) Sus sales heredadas de bcrypt no serán bastante aleatorias, sino solo no aleatorias en relación con el hash PHPass interno que aún no conoce el atacante .

Debido a que cada bcrypt y PHPass aún se salan al azar en relación con todos los demás hash de su tipo, la distribución de sales aún proporciona la amplia resistencia a la fuerza bruta que se supone que tienen las sales.

No puedo pensar en una forma en que saber el PHPass por adelantado proporcionaría alguna ventaja adicional al atacante. E incluso si proporciona una ventaja leve , es casi seguro que se verá superada por el mayor costo de craqueo bcrypt.

    
respondido por el Royce Williams 23.03.2017 - 18:45
fuente
2

Inicialmente iba a cerrar esto como un duplicado de " por qué-es-hash-una-contraseña-con-múltiples-hash-funciones-inútiles " sin embargo, tiene un caso un poco más complejo en el que ya tiene una base de datos de contraseñas con hash.

Si considera que su mecanismo de hashing existente es insuficiente del que necesita para migrar a una mejor solución. Eso significa que debe poder discriminar entre la representación antigua y la nueva, ejecutar los mecanismos de verificación en paralelo y convertir el texto claro de la representación antigua a la nueva. Y la única vez que obtiene el texto claro es cuando alguien inicia sesión.

Aunque PHPPass es bastante largo en el diente, utiliza pez globo (y bcrypt está basado en pez globo). Quizás no estés mejorando la seguridad tanto como crees.

    
respondido por el symcbean 23.03.2017 - 14:35
fuente
2

Tendré la tendencia a decir que si se está alejando de phpass, querrá eliminarlo de su base de código tanto como sea posible. Podría sugerirle que primero reemplace todos los phpasses con la versión cifrada de ellos, y luego reemplace su hash phpass con el hash bcrypt la próxima vez que un usuario inicie sesión. Para admitir a los usuarios que inician sesión por primera vez desde el cambio, También debe verificar si el phpass coincide.

Así que algo como lo siguiente. Obviamente estoy usando un pseudo código ya que la función no se llama "bcrypt".

if bcrypt(phpass($supplied_password)) == $storred_password;
    $storred_password = bcrypt($supplied_password);
    login();
if bcrypt($supplied_password) == $storred_password;
    login();

En este escenario, estás migrando lentamente al nuevo esquema de contraseña, pero el anterior aún es compatible.

Si hay alguna vulnerabilidad en phpass, como una pérdida de memoria o algo loco, no la está utilizando en la mayoría de sus contraseñas cuando los usuarios inician sesión.

    
respondido por el MikeSchem 23.03.2017 - 15:44
fuente
0

Lo que estás haciendo es esencialmente una expansión de teclas . Pero phpPass ya lo hace (al igual que bcrypt ), por lo que lo que realmente está haciendo desde un punto de vista de seguridad es (ligeramente) aumentar la seguridad al agregar una ronda más, nada más.

Puede haber algunas vulnerabilidades de implementación en phpPass que pueden llevar a la revelación de claves (por ejemplo, no a la eliminación de búferes de memoria), pero las posibilidades de explotación parecen ser pequeñas.

En general, diría que no disminuye la seguridad, incluso si es probable que no la aumente significativamente.

Aun así, podría valer la pena buscar alguna forma de migrar la base de datos. Por ejemplo, agregar un campo a la tabla de usuario para contener un hash bcrypt puro (o NULL). Si es NULL, se usa el algoritmo phpPass, y si la contraseña se valida, se genera el campo bcrypt. Puede controlar el porcentaje de campos hash rellenos con bcrypt para ver cómo se está realizando la migración. Y puede poner a cero el hash phpPass de algunos usuarios migrados de prueba para verificar que todo funciona correctamente si está parado solo en bcrypt (si el sistema está diseñado de forma limpia, esto es superfluo, pero aún así es bueno poder mostrar un escenario de Happy Day al CEO: una tabla con coberturas de código no lo corta tanto.

    
respondido por el LSerni 23.03.2017 - 15:25
fuente

Lea otras preguntas en las etiquetas