Saltar al contenido principal

¿Qué es hashear?

Hashear consiste en transformar mediante una función unidireccional un dato en claro (por ejemplo, una contraseña) a una cadena de longitud fija. La misma entrada produce siempre el mismo hash, pero no es posible recuperar el texto en claro a partir del hash. La fachada Hash de Laravel soporta los algoritmos bcrypt y Argon2 para el almacenamiento seguro de contraseñas.

Comparación de algoritmos

AlgoritmoCaracterísticasUso recomendado
bcryptPermite ajustar el coste con el work factor (rounds). Por defectoAplicaciones web habituales
argon2iPermite ajustar memoria, tiempo y número de hilos. Resistente a ataques de canal lateralEscenarios con requisitos de alta seguridad
argon2idHíbrido de argon2i y argon2d. Recomendado por PHCProyectos nuevos que usen Argon2
El “work factor” de bcrypt controla el tiempo que se tarda en generar el hash. Cuanto más lento sea el hash, mayor será la resistencia frente a ataques de fuerza bruta. A medida que el hardware se vuelve más rápido, puedes ir subiendo el work factor para mantener el nivel de seguridad.

Flujo de hasheo y verificación


Configuración

Por defecto, Laravel usa el driver bcrypt. Puedes cambiarlo con la variable de entorno HASH_DRIVER.
# .env
HASH_DRIVER=bcrypt  # bcrypt / argon / argon2id
Para personalizar la configuración de hashing, publica el archivo de configuración con config:publish.
php artisan config:publish hashing
Tras publicarlo, puedes modificar el work factor por defecto y otras opciones en config/hashing.php.

Uso básico

Hashear una contraseña

Al pasar el texto en claro a Hash::make() se devuelve el hash. Ese hash es lo que guardas en la base de datos.
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class PasswordController extends Controller
{
    public function update(Request $request): RedirectResponse
    {
        $request->validate([
            'password' => ['required', 'min:8', 'confirmed'],
        ]);

        $request->user()->fill([
            'password' => Hash::make($request->password),
        ])->save();

        return redirect('/profile');
    }
}
Guarda el hash en la base de datos, pero nunca guardes la contraseña en claro.

Ajustar el work factor de bcrypt

La opción rounds ajusta el coste de generar el hash. Cuanto mayor sea el valor, más seguro, pero también más lento. El valor por defecto (12) es adecuado para la mayoría de aplicaciones.
$hashed = Hash::make('plain-text-password', [
    'rounds' => 14,
]);

Ajustar el work factor de Argon2

Con Argon2 puedes ajustar el coste con las opciones memory, time y threads.
$hashed = Hash::make('plain-text-password', [
    'memory'  => 65536, // en KiB
    'time'    => 4,
    'threads' => 2,
]);
OpciónDescripciónPor defecto
memoryCantidad de memoria (KiB)65536
timeNúmero de iteraciones4
threadsNúmero de hilos1
Para los detalles de las opciones de Argon2, consulta la documentación oficial de PHP.

Verificación de contraseñas

Con Hash::check() puedes comprobar si una contraseña en claro coincide con el hash guardado. Es un uso típico dentro del proceso de login.
use Illuminate\Support\Facades\Hash;

if (Hash::check($request->password, $user->password)) {
    // La contraseña coincide
} else {
    // La contraseña no coincide
}
Si utilizas Auth::attempt(), esto se hace automáticamente y no necesitas llamarlo directamente. Hash::check() es útil cuando quieres comprobar la contraseña actual manualmente.
// Ejemplo: comprobar la contraseña actual en un formulario de cambio de contraseña
if (! Hash::check($request->current_password, $request->user()->password)) {
    return back()->withErrors(['current_password' => 'La contraseña actual no es correcta.']);
}

Detección de necesidad de rehash

Con Hash::needsRehash() puedes comprobar si el work factor con el que se generó el hash es distinto de la configuración actual. Se usa para actualizar los hashes existentes tras haber cambiado el work factor.
use Illuminate\Support\Facades\Hash;

if (Hash::needsRehash($user->password)) {
    $user->update([
        'password' => Hash::make($plainTextPassword),
    ]);
}
Ejemplo de rehash al iniciar sesión con éxito:
// Rehash dentro del proceso de login
if (Auth::attempt($credentials)) {
    if (Hash::needsRehash(Auth::user()->password)) {
        Auth::user()->update([
            'password' => Hash::make($credentials['password']),
        ]);
    }

    return redirect()->intended('/dashboard');
}
Revisa periódicamente el work factor a medida que mejora el hardware para mantener el nivel de seguridad. Usar needsRehash() te permite actualizar las contraseñas en el momento natural del login del usuario.

Verificación del algoritmo del hash

Por defecto, Hash::check() verifica que el hash se haya generado con el algoritmo configurado actualmente. Si el algoritmo difiere, se lanza una RuntimeException. Esto ayuda a prevenir ataques por manipulación del algoritmo del hash. Si estás migrando algoritmos y necesitas soportar varios simultáneamente, puedes desactivar esta verificación estableciendo HASH_VERIFY a false.
# .env
HASH_VERIFY=false
Con HASH_VERIFY=false se desactiva la verificación del algoritmo. Úsalo solo durante el periodo de migración y, cuando termines, vuelve a true (valor por defecto).

Resumen

ObjetivoMétodo
Hashear una contraseñaHash::make($password)
Verificar un hashHash::check($plain, $hash)
Comprobar si hace falta rehashHash::needsRehash($hash)
Cambiar el driver de hashVariable de entorno HASH_DRIVER
Desactivar la verificación de algoritmoHASH_VERIFY=false

Próximos pasos

Introducción a la autenticación

Aprende una visión general de la autenticación, incluida la implementación del login con Hash::check().
Última modificación el 13 de julio de 2026