como-usar-sha256-esp32

Qué es y cómo usar SHA-256 en ESP32

En esta entrada vamos a ver qué es y cómo usar SHA-256, cómo funciona y cómo utilizarlo en un ESP32.

SHA-256 es un algoritmo de hashing considerado seguro que nos será muy útil a la hora de hacer tarea cómo:

  • Autenticación: Validar la identidad de los dispositivos o usuarios.
  • Almacenamiento seguro: Proteger contraseñas y claves en dispositivos embebidos.
  • Verificar la integridad de los datos: Asegurar que los datos no han sido alterados durante la transmisión.

Pero antes vamos a ver brevemente que es el SHA-256 👇.

Qué es SHA-256

SHA-256 es un miembro de la familia de funciones hash SHA-2 (Secure Hash Algorithm 2) desarrolladas por el Instituto Nacional de Estándares y Tecnología (NIST).

Esta función hash toma una entrada de datos de cualquier longitud y genera un valor de 256 bits (32 bytes) que se representa como un valor hexadecimal de 64 dígitos

Características principales de SHA-256

  • Tamaño de salida: 256 bits (32 bytes).
  • Resistencia a colisiones: Es computacionalmente inviable encontrar dos entradas diferentes que produzcan el mismo hash.
  • Determinista: La misma entrada siempre producirá el mismo hash.
  • Irreversible: No es posible reconstruir la entrada original a partir del hash.

El hash SHA-256 es una representación única y fija de los datos originales, lo que significa que cualquier cambio en los datos generará un hash completamente diferente.

SHA-256 es un algoritmo unidireccional, lo que significa que no es posible obtener los datos originales a partir del hash.

Esto lo convierte en una herramienta muy útil para verificar la integridad de los datos y protegernos contra modificaciones no autorizadas.

Implementación de SHA-256 en el ESP32

El ESP32 cuenta con un módulo de hardware de cifrado que incluye soporte para SHA-256. Esto permite realizar operaciones de hash de manera eficiente sin sobrecargar la CPU.

Vamos a ver cómo implementar SHA-256 en el ESP32 utilizando la biblioteca mbedTLS.

#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> generateSHA256(std::string& text)
{
	std::vector<uint8_t> hash(32);

	mbedtls_md_context_t ctx;
	mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;

	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 = generateSHA256(message);

	Serial.print(message.c_str());
	Serial.print("\nHash: ");
	printBlockAsHex(hash);
}

void loop() {}
  • input: Es la cadena de texto que queremos hashear.
  • input_len: Longitud de la cadena de entrada.
  • output: Un array de 32 bytes para almacenar el hash resultante.
  • mbedtls_sha256_context: Estructura que almacena el estado del cálculo de hash.
  • mbedtls_sha256_init: Inicializa el contexto.
  • mbedtls_sha256_starts: Inicia el cálculo del hash (el segundo parámetro 0 indica que usamos SHA-256).
  • mbedtls_sha256_update: Procesa la cadena de entrada.
  • mbedtls_sha256_finish: Finaliza el cálculo y almacena el hash en el buffer de salida.
  • mbedtls_sha256_free: Libera los recursos del contexto.

Al ejecutarlo tendréis algo como esto

sha256

Ejemplos prácticos