Saltar al contenido

Funciones hash criptográficas

Una guía centrada en la verificación de las funciones hash criptográficas que aborda sus propiedades de seguridad, la codificación de bytes, SHA-2, SHA-3, Keccak, sus usos en cadenas de bloques y los riesgos de implementación.

Actualizado

Solo con fines educativos; no constituye asesoramiento de inversión ni sobre implementaciones criptográficas. La coincidencia de un resumen no demuestra por sí sola autenticidad, propiedad, autorización, finalidad ni disponibilidad de los datos.

Respuesta directa

Una función hash criptográfica asigna de forma determinista un mensaje representado como bytes a un resumen de longitud de salida definida. Para un hash de longitud fija de n bits, la relación básica es:

h = H(m), where h is in {0,1}^n

Los mismos bytes y el mismo algoritmo producen el mismo resumen. Un cambio de un bit en la entrada debería alterar de manera impredecible muchos bits de la salida, pero este efecto avalancha no constituye la definición de seguridad. Los objetivos de seguridad principales son la resistencia a la preimagen (dado un resumen, es inviable encontrar una entrada que lo produzca), la resistencia a la segunda preimagen (dada una entrada, es inviable encontrar otra distinta con el mismo resumen) y la resistencia a las colisiones (es inviable encontrar dos entradas distintas cualesquiera con el mismo resumen).

El hashing no es cifrado: no existe una clave de descifrado ni se garantiza que la entrada pueda recuperarse. Como una cantidad infinita de mensajes posibles se asigna a un espacio de salida finito, necesariamente existen colisiones; la seguridad significa que encontrar una que resulte útil es computacionalmente inviable para el algoritmo y la longitud de salida elegidos.

Un resumen tampoco aporta autenticidad por sí solo. Volver a calcular el hash de un archivo solo detecta una discrepancia cuando el resumen esperado y el algoritmo se obtuvieron mediante un canal de confianza. Los protocolos logran garantías más sólidas combinando hashes con firmas, códigos de autenticación de mensajes, estructuras de datos autenticadas, reglas de consenso o prueba de trabajo.

Cómo funciona

  1. Definir los bytes exactos. La codificación del texto, el uso de mayúsculas, los espacios en blanco, el orden de los campos, la representación de enteros, los prefijos de longitud y la serialización afectan a m. Un protocolo debe especificar una codificación canónica y vincular el hash a un algoritmo, una versión, una red y una finalidad.
  2. Ejecutar la construcción especificada. SHA-256 preprocesa un mensaje de longitud acotada, lo divide en bloques y actualiza de forma iterativa un estado interno. SHA3-256 emplea una construcción de esponja basada en KECCAK. Ambas devuelven resúmenes de 256 bits, pero son funciones distintas y sus resultados no son intercambiables.
  3. Interpretar la seguridad según la propiedad requerida. Para un hash ideal de n bits, una búsqueda genérica de preimagen requiere alrededor de 2^n evaluaciones, mientras que una búsqueda genérica de colisiones requiere aproximadamente 2^(n/2) debido al efecto del cumpleaños. La longitud de salida no basta si el algoritmo está comprometido, el resumen está truncado o el protocolo que lo rodea presenta fallos.
  4. Construir el protocolo en torno al resumen. Un esquema de firma digital puede firmar el resumen de un mensaje; HMAC añade una clave secreta para autenticar mensajes; un árbol de Merkle compromete muchas hojas mediante una sola raíz; y la prueba de trabajo calcula repetidamente hashes de cabeceras de bloque candidatas hasta que un resumen satisface un objetivo. Estas construcciones ofrecen garantías diferentes.
  5. Utilizar la función exacta de la cadena. Las cabeceras de bloque y los nodos de Merkle de Bitcoin emplean SHA-256 doble con el orden de bytes especificado. La ejecución de Ethereum utiliza Keccak-256, procedente del diseño KECCAK anterior a su estandarización, y no el SHA3-256 estandarizado. Por tanto, una etiqueta como «hash de 256 bits» no basta para verificar.
  6. Verificar el contexto antes de interpretar el resultado. Hay que comprobar la fuente del resumen esperado, el identificador del algoritmo, la codificación de bytes, el dominio o la cadena, la referencia de bloque y estado, el estado de confirmación y cualquier truncamiento. Un cálculo correcto aplicado al contexto equivocado sigue siendo una verificación fallida.

Ejemplos prácticos

  • Un cambio mínimo en la entrada. El SHA-256 de los cinco bytes UTF-8 de hello es 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824. Sustituir el primer byte por la H mayúscula produce 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969. Los resúmenes distintos no revelan qué byte cambió.
  • La fortaleza de seguridad no equivale a la longitud del resumen en todos los modelos de ataque. Un hash ideal de 256 bits ofrece aproximadamente 2^256 operaciones de resistencia a la preimagen, pero 2^128 frente a colisiones. Esta distinción importa cuando un protocolo depende de la resistencia a colisiones, como suele ocurrir en los flujos de firma digital.
  • Una prueba de Merkle autentica la inclusión con respecto a una raíz concreta. El verificador calcula el hash de la hoja codificada con cada nodo hermano proporcionado, en el orden especificado, hasta reconstruir la raíz comprometida. Una coincidencia no demuestra que la raíz sea definitiva, que los datos de la hoja sean verdaderos ni que los datos omitidos estén disponibles.
  • La prueba de trabajo añade una regla de objetivo. Bitcoin solo valida una cabecera candidata cuando su valor SHA-256 doble, interpretado según las reglas de consenso, es menor o igual que el objetivo codificado. El resumen no adquiere mayor resistencia a colisiones porque los mineros hayan realizado más trabajo.

Riesgos

  • Usar un algoritmo obsoleto o inadecuado, en especial confiar en SHA-1 cuando se requiere resistencia a colisiones.
  • Tratar SHA3-256, Keccak-256, SHA-256, SHA-256 doble y las distintas variantes truncadas como si fueran intercambiables.
  • Calcular el hash del texto mostrado en lugar de los bytes canónicos, u omitir la normalización Unicode, los espacios en blanco, el orden de bytes, el orden de los campos y la codificación de longitudes.
  • Descargar un archivo y su resumen esperado desde la misma ubicación comprometida, lo que no aporta una comprobación de integridad independiente.
  • Utilizar directamente un hash rápido de propósito general para almacenar contraseñas, en vez de un esquema de hashing de contraseñas con sal, diseñado para ese fin y con un factor de trabajo adecuado.
  • Utilizar H(secret || message) como código de autenticación improvisado; algunas construcciones hash iterativas permiten ataques de extensión de longitud, mientras que HMAC está diseñado para la autenticación con clave.
  • Truncar resúmenes sin calcular la seguridad resultante frente a colisiones y preimágenes para la escala y el modelo de amenazas del protocolo.
  • Reutilizar una codificación entre protocolos sin separación de dominios, permitiendo que un resumen válido en un contexto se interprete en otro.
  • Suponer que el hash de una transacción demuestra su confirmación, finalidad, ejecución correcta, propiedad o ausencia de reorganizaciones de la cadena.
  • Suponer que un hash de contenido hace recuperables los datos referenciados; un compromiso puede seguir siendo válido aunque desaparezcan todas las copias disponibles.
  • Comparar cadenas de caracteres de exploradores sin comprobar el orden de bytes, las reglas de prefijos, la serialización o si la interfaz muestra de manera distinta un identificador interno.
  • Implementar primitivas criptográficas sin vectores de prueba estándar, bibliotecas mantenidas, revisión independiente y procedimientos de actualización.

Errores comunes

  • Un hash son datos cifrados. El cifrado es reversible con la clave adecuada; un hash criptográfico es un resumen unidireccional sin operación de descifrado.
  • Dos entradas distintas nunca pueden compartir un resumen. Las colisiones existen necesariamente cuando la salida tiene longitud fija. Un diseño seguro hace que encontrarlas y explotarlas resulte inviable.
  • Un resumen de 256 bits siempre proporciona 256 bits de seguridad. La resistencia genérica a colisiones de un hash ideal de 256 bits es de unos 128 bits, y las decisiones del protocolo pueden reducirla aún más.
  • La coincidencia de hashes demuestra quién creó el mensaje. Un hash sin más no contiene ningún secreto ni autentica a ningún remitente; cuando importa el origen, hay que usar una firma o un MAC adecuado.
  • Keccak-256 y SHA3-256 son dos nombres para la misma función. Emplean diseños estrechamente relacionados, pero parámetros de estandarización diferentes, y producen resúmenes distintos.
  • El hash de una transacción en cadena demuestra su liquidación. Identifica los datos codificados de la transacción; la inclusión en la cadena, el estado de ejecución, las confirmaciones y la finalidad son hechos independientes.

Temas relacionados

Fuentes

Navegación

Buscar en la wiki...