Encriptación MD5

Herramienta de hash MD5

Resumen de la herramienta: Herramienta de Cifrado Hash MD5

MD5 (Message Digest Algorithm 5) es una función hash criptográfica que genera un valor hash de 128 bits (32 caracteres hexadecimales) a partir de datos de entrada de cualquier longitud. Se utiliza ampliamente para verificación de integridad de datos, hash de contraseñas, generación de claves de caché y otros propósitos.

¿Qué es Herramienta de Cifrado Hash MD5?

Herramienta de Cifrado Hash MD5 codifica/decodifica contenido o genera checksums para verificación.

Cómo usarlo

  1. Pega el contenido o ingresa el texto.
  2. Elige el modo de codificación o hash.
  3. Copia el resultado generado.

Casos de uso comunes

  • Firmas y verificación de integridad
  • Transmisión segura entre sistemas
  • Validación rápida durante el debug

❓ Preguntas frecuentes

P1: ¿Resultados distintos con el mismo input?
R: Revisa la codificación y caracteres ocultos.

P2: ¿Se puede revertir?
R: La codificación es reversible; el hash no.

P3: ¿Entrada grande?
R: Divide en partes pequeñas para estabilidad.

✨ Características Principales

  • 🔐 Hash Rápido: Convierte texto instantáneamente a valores hash MD5
  • 🌐 Soporte Multiidioma: Compatible con caracteres Unicode como español, chino, inglés
  • 📊 Garantía de Unicidad: Genera siempre el mismo valor hash para la misma entrada
  • 📋 Copia con Un Clic: Los valores hash generados se pueden copiar directamente
  • Generación en Tiempo Real: Muestra valores hash al mismo tiempo que la entrada

📖 Ejemplos de Uso

Hash de Texto

Texto de Entrada:

¡Hola, mundo!

Valor Hash MD5:

b8c9d3f5e6a7b2c4d1e8f9a0b3c6d9e2

Hash de Contraseña

Contraseña de Entrada:

MiContraseñaSegura123!

Valor Hash MD5:

5d41402abc4b2a76b9719d911017c592

Hash de Nombre de Archivo

Nombre de Archivo de Entrada:

documento_importante_2024.pdf

Valor Hash MD5:

a1b2c3d4e5f6789012345678901234ab

🎯 Escenarios de Aplicación

1. Verificación de Integridad de Datos

Verificar la integridad de archivos y datos:

// Cálculo de checksum MD5 de archivo
const calcularMD5Archivo = async (archivo) => {
  return new Promise((resolver, rechazar) => {
    const lector = new FileReader();
    
    lector.onload = async (evento) => {
      try {
        const arrayBuffer = evento.target.result;
        const hashBuffer = await crypto.subtle.digest('MD5', arrayBuffer);
        const hashArray = Array.from(new Uint8Array(hashBuffer));
        const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
        resolver(hashHex);
      } catch (error) {
        rechazar(error);
      }
    };
    
    lector.onerror = rechazar;
    lector.readAsArrayBuffer(archivo);
  });
};

// Sistema de verificación de integridad de datos
class VerificadorIntegridad {
  constructor() {
    this.checksums = new Map();
  }

  // Registrar checksum de datos
  registrarChecksum(idDatos, datos) {
    const checksum = this.calcularMD5(datos);
    this.checksums.set(idDatos, checksum);
    return checksum;
  }

  // Verificar integridad de datos
  verificarIntegridad(idDatos, datosActuales) {
    const checksumOriginal = this.checksums.get(idDatos);
    if (!checksumOriginal) {
      return { valido: false, razon: 'Checksum no registrado' };
    }

    const checksumActual = this.calcularMD5(datosActuales);
    const esValido = checksumOriginal === checksumActual;

    return {
      valido: esValido,
      checksumOriginal,
      checksumActual,
      razon: esValido ? 'Integridad OK' : 'Los datos han sido modificados'
    };
  }

  calcularMD5(datos) {
    // Implementación de cálculo MD5 (en implementación real usar librería crypto)
    return CryptoJS.MD5(datos).toString();
  }
}

// Ejemplo de uso
const verificadorIntegridad = new VerificadorIntegridad();

// Registrar datos
const datosOriginales = "Datos importantes de negocio";
const checksum = verificadorIntegridad.registrarChecksum('datos001', datosOriginales);
console.log('Checksum registrado:', checksum);

// Verificar integridad de datos más tarde
const datosActuales = "Datos importantes de negocio"; // Sin cambios
const verificacion = verificadorIntegridad.verificarIntegridad('datos001', datosActuales);
console.log('Resultado de verificación de integridad:', verificacion);

2. Generación de Claves de Caché

Construir un sistema de caché eficiente:

// Gestor de caché
class GestorCache {
  constructor() {
    this.cache = new Map();
    this.tamañoMaximo = 1000;
  }

  // Generar clave de caché
  generarClaveCache(parametros) {
    // Convertir parámetros a cadena
    const cadenaParametros = JSON.stringify(parametros, Object.keys(parametros).sort());
    
    // Generar clave con hash MD5
    return CryptoJS.MD5(cadenaParametros).toString();
  }

  // Obtener datos (prioridad de caché)
  async obtenerDatos(parametros, funcionObtener) {
    const claveCache = this.generarClaveCache(parametros);
    
    // Verificar desde caché
    if (this.cache.has(claveCache)) {
      console.log('Acierto de caché:', claveCache);
      return this.cache.get(claveCache);
    }

    // Si no está en caché, obtener nuevos datos
    console.log('Fallo de caché, obteniendo datos:', claveCache);
    const datos = await funcionObtener(parametros);
    
    // Guardar en caché
    this.establecerCache(claveCache, datos);
    
    return datos;
  }

  // Guardar en caché
  establecerCache(clave, datos) {
    // Limitación de tamaño de caché
    if (this.cache.size >= this.tamañoMaximo) {
      const primeraClave = this.cache.keys().next().value;
      this.cache.delete(primeraClave);
    }

    this.cache.set(clave, {
      datos: datos,
      timestamp: Date.now()
    });
  }

  // Limpiar caché
  limpiarCache() {
    this.cache.clear();
  }

  // Eliminar caché expirado
  limpiarCacheExpirado(edadMaxima = 3600000) { // 1 hora
    const ahora = Date.now();
    for (const [clave, valor] of this.cache.entries()) {
      if (ahora - valor.timestamp > edadMaxima) {
        this.cache.delete(clave);
      }
    }
  }
}

// Ejemplo de llamada API
const gestorCache = new GestorCache();

const obtenerDatosUsuario = async (idUsuario) => {
  const respuesta = await fetch(`/api/users/${idUsuario}`);
  return await respuesta.json();
};

// Obtener datos usando caché
const obtenerDatosUsuarioConCache = async (idUsuario) => {
  return await gestorCache.obtenerDatos(
    { endpoint: 'users', idUsuario: idUsuario },
    () => obtenerDatosUsuario(idUsuario)
  );
};

// Ejemplo de uso
obtenerDatosUsuarioConCache('user123').then(datos => {
  console.log('Datos de usuario:', datos);
});

3. Detección de Datos Duplicados

Detección de duplicados en bases de datos o sistemas de archivos:

// Sistema de detección de duplicados
class DetectorDuplicados {
  constructor() {
    this.hashes = new Set();
    this.hashADatos = new Map();
  }

  // Agregar datos y verificar duplicados
  agregarDatos(datos, metadatos = {}) {
    const hash = this.calcularMD5(datos);
    
    if (this.hashes.has(hash)) {
      return {
        esDuplicado: true,
        hash: hash,
        datosExistentes: this.hashADatos.get(hash),
        mensaje: 'Se detectaron datos duplicados'
      };
    }

    // Agregar como nuevos datos
    this.hashes.add(hash);
    this.hashADatos.set(hash, {
      datos: datos,
      metadatos: metadatos,
      agregadoEn: new Date().toISOString()
    });

    return {
      esDuplicado: false,
      hash: hash,
      mensaje: 'Agregado como nuevos datos'
    };
  }

  // Verificar duplicado de archivo
  async verificarDuplicadoArchivo(archivo) {
    return new Promise((resolver, rechazar) => {
      const lector = new FileReader();
      
      lector.onload = (evento) => {
        try {
          const contenido = evento.target.result;
          const hash = CryptoJS.MD5(contenido).toString();
          
          const resultado = this.agregarDatos(contenido, {
            nombreArchivo: archivo.name,
            tamañoArchivo: archivo.size,
            tipoArchivo: archivo.type,
            ultimaModificacion: archivo.lastModified
          });

          resolver({
            ...resultado,
            infoArchivo: {
              nombre: archivo.name,
              tamaño: archivo.size,
              tipo: archivo.type
            }
          });
        } catch (error) {
          rechazar(error);
        }
      };
      
      lector.onerror = rechazar;
      lector.readAsText(archivo);
    });
  }

  calcularMD5(datos) {
    return CryptoJS.MD5(datos).toString();
  }

  // Obtener estadísticas
  obtenerEstadisticas() {
    return {
      totalHashes: this.hashes.size,
      totalDatos: this.hashADatos.size,
      usoMemoria: this.estimarUsoMemoria()
    };
  }

  estimarUsoMemoria() {
    let tamañoTotal = 0;
    for (const [hash, datos] of this.hashADatos.entries()) {
      tamañoTotal += hash.length * 2; // cadena hash
      tamañoTotal += JSON.stringify(datos).length * 2; // datos
    }
    return `${(tamañoTotal / 1024).toFixed(2)} KB`;
  }

  // Limpiar datos
  limpiar() {
    this.hashes.clear();
    this.hashADatos.clear();
  }
}

// Ejemplo de uso
const detectorDuplicados = new DetectorDuplicados();

// Verificar duplicado de datos de texto
const datosTexto1 = "Este es un documento importante.";
const datosTexto2 = "Este es un documento importante."; // Mismo contenido
const datosTexto3 = "Este es otro documento.";

console.log(detectorDuplicados.agregarDatos(datosTexto1, { fuente: 'documento1.txt' }));
console.log(detectorDuplicados.agregarDatos(datosTexto2, { fuente: 'documento2.txt' })); // Detectar duplicado
console.log(detectorDuplicados.agregarDatos(datosTexto3, { fuente: 'documento3.txt' }));

// Verificar duplicado de archivo
const entradaArchivo = document.getElementById('entradaArchivo');
entradaArchivo.addEventListener('change', async (evento) => {
  const archivos = evento.target.files;
  
  for (const archivo of archivos) {
    try {
      const resultado = await detectorDuplicados.verificarDuplicadoArchivo(archivo);
      console.log(`Archivo ${archivo.name}:`, resultado);
    } catch (error) {
      console.error('Error al procesar archivo:', error);
    }
  }
});

4. Gestión de Sesiones

Identificación de sesiones en aplicaciones web:

// Sistema de gestión de sesiones
class GestorSesiones {
  constructor() {
    this.sesiones = new Map();
    this.tiempoExpiracionSesion = 30 * 60 * 1000; // 30 minutos
  }

  // Generar ID de sesión
  generarIdSesion(infoUsuario) {
    const timestamp = Date.now();
    const valorAleatorio = Math.random().toString(36);
    const agenteUsuario = navigator.userAgent;
    
    const datosSesion = `${infoUsuario.idUsuario}_${timestamp}_${valorAleatorio}_${agenteUsuario}`;
    return CryptoJS.MD5(datosSesion).toString();
  }

  // Crear sesión
  crearSesion(infoUsuario) {
    const idSesion = this.generarIdSesion(infoUsuario);
    
    const sesion = {
      id: idSesion,
      idUsuario: infoUsuario.idUsuario,
      agenteUsuario: navigator.userAgent,
      direccionIP: infoUsuario.direccionIP || 'desconocida',
      creadaEn: new Date(),
      ultimoAcceso: new Date(),
      activa: true,
      datos: {}
    };

    this.sesiones.set(idSesion, sesion);
    
    // Configurar expiración automática
    setTimeout(() => {
      this.expirarSesion(idSesion);
    }, this.tiempoExpiracionSesion);

    return idSesion;
  }

  // Obtener sesión
  obtenerSesion(idSesion) {
    const sesion = this.sesiones.get(idSesion);
    
    if (sesion && sesion.activa) {
      // Actualizar tiempo de último acceso
      sesion.ultimoAcceso = new Date();
      return sesion;
    }
    
    return null;
  }

  // Actualizar datos de sesión
  actualizarDatosSesion(idSesion, datos) {
    const sesion = this.obtenerSesion(idSesion);
    if (sesion) {
      sesion.datos = { ...sesion.datos, ...datos };
      return true;
    }
    return false;
  }

  // Invalidar sesión
  invalidarSesion(idSesion) {
    const sesion = this.sesiones.get(idSesion);
    if (sesion) {
      sesion.activa = false;
      this.sesiones.delete(idSesion);
      return true;
    }
    return false;
  }

  // Procesar expiración de sesión
  expirarSesion(idSesion) {
    const sesion = this.sesiones.get(idSesion);
    if (sesion) {
      const ahora = new Date();
      const ultimoAcceso = new Date(sesion.ultimoAcceso);
      const diferenciaTiempo = ahora - ultimoAcceso;

      if (diferenciaTiempo > this.tiempoExpiracionSesion) {
        this.invalidarSesion(idSesion);
        console.log(`Sesión ${idSesion} ha expirado`);
      }
    }
  }

  // Obtener sesiones activas
  obtenerSesionesActivas(idUsuario) {
    const sesionesusuario = [];
    
    for (const [idSesion, sesion] of this.sesiones) {
      if (sesion.idUsuario === idUsuario && sesion.activa) {
        sesionesusuario.push({
          id: idSesion,
          creadaEn: sesion.creadaEn,
          ultimoAcceso: sesion.ultimoAcceso,
          agenteUsuario: sesion.agenteUsuario,
          direccionIP: sesion.direccionIP
        });
      }
    }
    
    return sesionesusuario;
  }

  // Estadísticas de sesión
  obtenerEstadisticasSesion() {
    let conteoActivas = 0;
    let conteoTotal = this.sesiones.size;
    
    for (const sesion of this.sesiones.values()) {
      if (sesion.activa) {
        conteoActivas++;
      }
    }

    return {
      total: conteoTotal,
      activas: conteoActivas,
      inactivas: conteoTotal - conteoActivas
    };
  }
}

// Ejemplo de uso
const gestorSesiones = new GestorSesiones();

// Crear sesión al iniciar sesión
const iniciarSesionUsuario = (credencialesUsuario) => {
  // Proceso de autenticación de usuario (omitido)
  const infoUsuario = {
    idUsuario: 'user123',
    nombreUsuario: 'juan@example.com',
    direccionIP: '192.168.1.100'
  };

  const idSesion = gestorSesiones.crearSesion(infoUsuario);
  
  // Guardar ID de sesión en cookie
  document.cookie = `idSesion=${idSesion}; path=/; max-age=1800`; // 30 minutos
  
  console.log('Inicio de sesión exitoso, ID de sesión:', idSesion);
  return idSesion;
};

// Verificar sesión
const verificarSesion = () => {
  const cookies = document.cookie.split(';');
  const cookieSesion = cookies.find(cookie => cookie.trim().startsWith('idSesion='));
  
  if (cookieSesion) {
    const idSesion = cookieSesion.split('=')[1];
    const sesion = gestorSesiones.obtenerSesion(idSesion);
    
    if (sesion) {
      console.log('Sesión válida:', sesion);
      return sesion;
    }
  }
  
  console.log('No hay sesión válida');
  return null;
};

// Cerrar sesión
const cerrarSesionUsuario = () => {
  const sesion = verificarSesion();
  if (sesion) {
    gestorSesiones.invalidarSesion(sesion.id);
    document.cookie = 'idSesion=; path=/; max-age=0'; // Eliminar cookie
    console.log('Sesión cerrada');
  }
};

🔧 Detalles Técnicos

Algoritmo MD5

Características básicas de MD5:

Longitud de Hash: 128 bits (32 caracteres hexadecimales)
Tamaño de Bloque: 512 bits
Velocidad de Procesamiento: Alta
Resistencia a Colisiones: Baja (actualmente no recomendado)

Consideraciones de Seguridad

Limitaciones de MD5 y alternativas:

// Limitaciones de MD5
const limitaciones = {
  colision: 'MD5 es vulnerable a ataques de colisión',
  preimagen: 'Baja resistencia a ataques de primera preimagen',
  arcoiris: 'Posibles ataques de tabla arcoíris',
  recomendacion: 'Se recomienda SHA-256 o superior para usos que requieren seguridad'
};

// Alternativas más seguras
const alternativasSeguras = {
  'SHA-256': 'Función hash más fuerte',
  'SHA-3': 'Función hash estándar más reciente',
  'bcrypt': 'Específico para hash de contraseñas',
  'scrypt': 'Función de memoria dura',
  'Argon2': 'Función hash de contraseñas más reciente'
};

// Implementación recomendada para hash de contraseñas
const hashContraseña = async (contraseña, sal) => {
  // Se recomienda usar bcrypt o Argon2 en lugar de MD5
  const codificador = new TextEncoder();
  const datos = codificador.encode(contraseña + sal);
  const hashBuffer = await crypto.subtle.digest('SHA-256', datos);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
};

💡 Consejos de Uso

  • Selección de Uso: Limitar a usos donde la seguridad no es crítica (claves de caché, checksums, etc.)
  • Uso de Sal: Siempre usar sal al hacer hash de contraseñas
  • Considerar Alternativas: Usar SHA-256 o superior cuando la seguridad es importante
  • Rendimiento vs Seguridad: Elegir la función hash apropiada según el uso

⚠️ Notas Importantes

  • Seguridad: MD5 no es criptográficamente seguro, no usar para usos que requieren seguridad
  • Ataques de Colisión: Existe la posibilidad de que diferentes entradas generen el mismo valor hash
  • Contraseñas: Se recomienda usar bcrypt o Argon2 para hash de contraseñas
  • Limitación de Uso: Limitar a usos donde la seguridad no es crítica como verificación de integridad de datos o generación de claves de caché

🚀 Cómo Usar

  1. Entrada de Texto: Ingrese el texto a hacer hash en el cuadro de entrada
  2. Generación Automática: El valor hash MD5 se genera automáticamente al ingresar
  3. Verificación de Resultados: Verifique el valor hash hexadecimal de 32 caracteres
  4. Uso de Copia: Use el botón "Copiar" para copiar el valor hash al portapapeles
  5. Uso en Aplicaciones: Use para claves de caché, checksums, detección de duplicados, etc.

Consejo: Esta herramienta procesa localmente en el lado del cliente y no envía datos de entrada al servidor, protegiendo la privacidad.