El MD5 (Message Digest Algorithm 5) es un algoritmo de hash ampliamente utilizado para generar un valor de 128 bits (16 bytes) a partir de datos de entrada de cualquier tamaño.
Este valor hash es único para cada entrada, lo que significa que incluso un pequeño cambio en los datos de entrada generará un hash completamente diferente.
Como todo algoritmo de hash, el MD5 es un algoritmo unidireccional, Es decir, que no se puederevertir el proceso para obtener los datos originales a partir del resumen MD5 (no es encriptación, es hashing).
Características principales de MD5
- Tamaño del hash: 128 bits (16 bytes).
- Velocidad: MD5 es rápido y eficiente en términos de procesamiento.
- Determinista: La misma entrada siempre producirá el mismo hash.
- No reversible: No es posible recuperar los datos originales a partir del hash.
Aunque MD5 fue diseñado para ser seguro, se han descubierto vulnerabilidades que permiten colisiones (dos entradas diferentes que producen el mismo hash).
Por esta razón, no se recomienda para aplicaciones de seguridad.
Aunque no se recomienda para aplicaciones de seguridad , sigue siendo útil en contextos donde se necesita una verificación rápida de integridad de datos (como ficheros o comunicaciones).
Implementación de MD5 en el ESP32
El ESP32 cuenta con un módulo de hardware para operaciones criptográficas, pero también podemos utilizar bibliotecas de software para implementar MD5.
En este caso, usaremos la biblioteca MD5.h
, que es fácil de usar y está disponible en el entorno de desarrollo de Arduino.
Veamos cómo generar un hash MD5 a partir de una cadena de texto en el ESP32.
#include "mbedtls/md.h"
#include "stdlib.h"
void printBlockAsHex(std::vector<uint8_t> data)
{
for(int i = 0; i < data.size(); i++)
{
Serial.printf("%02X ", data[i]);
}
}
std::vector<uint8_t> generateMD5(std::string& text)
{
std::vector<uint8_t> hash(16);
mbedtls_md_context_t ctx;
mbedtls_md_type_t md_type = MBEDTLS_MD_MD5;
mbedtls_md_init(&ctx);
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0);
mbedtls_md_starts(&ctx);
mbedtls_md_update(&ctx, (const unsigned char*)text.c_str(), text.length());
mbedtls_md_finish(&ctx, hash.data());
mbedtls_md_free(&ctx);
return hash;
}
void setup()
{
Serial.begin(115200);
delay(2000);
std::string message = "www.luisllamas.es";
auto hash = generateMD5(message);
Serial.print(message.c_str());
Serial.print("\nHash: ");
printBlockAsHex(hash);
}
void loop() {}
- Incluir la biblioteca MD5:
#include <MD5.h>
permite usar las funciones de la biblioteca. - Cadena de entrada: Definimos una cadena de texto (
input
) que queremos hashear. - Generar el hash: Usamos la función
MD5(input)
para calcular el hash de la cadena. - Mostrar el resultado: Imprimimos la cadena original y su hash MD5 en el monitor serial.
Ejemplos prácticos
Aunque MD5 no es seguro para aplicaciones críticas, puede ser útil en los siguientes escenarios:
Verificación de integridad de datos
Podemos usar MD5 para verificar si un archivo o conjunto de datos ha sido alterado. Por ejemplo, al transmitir datos entre dispositivos, podemos enviar el hash MD5 junto con los datos. El receptor puede calcular el hash de los datos recibidos y compararlo con el hash enviado para detectar cambios.
String calcularHash(String datos) {
return MD5(datos);
}
bool verificarIntegridad(String datos, String hashEnviado) {
String hashCalculado = calcularHash(datos);
return hashCalculado == hashEnviado;
}
Generación de identificadores únicos
MD5 puede usarse para generar identificadores únicos a partir de datos como nombres de usuario, direcciones IP o timestamps. Estos identificadores son útiles en aplicaciones donde se necesita un valor único pero no se requiere seguridad criptográfica.
String generarID(String nombreUsuario) {
return MD5(nombreUsuario + String(millis()));
}