¿Qué es el algoritmo SHA-2 y cómo funciona?

Los piratas informáticos no se toman un descanso para tomar café. Por lo tanto, es imprescindible comprender cada término de ciberseguridad de adentro hacia afuera.

Es posible que hayas escuchado el término ‘algoritmo hash seguro’ en algún momento de tu viaje de seguridad cibernética.

La familia de algoritmos SHA-2 se usa ampliamente en nuestro mundo en línea y constituye un componente importante de nuestra seguridad en línea. Todavía se considera seguros en la mayoría de las aplicaciones y se prefiere al inseguro MD5 en la mayoría de los casos de uso.

Así que hoy, pongamos el límite de nuestra curiosidad y entendamos qué es el Algoritmo Hashing Seguro (SHA) y cómo funciona. Pero antes, analizaremos qué es una función hash y las funciones hash criptográficas.

¿Qué es una función hash?

Antes de que podamos entrar en los detalles de lo que es SHA-2, debemos cubrir los conceptos básicos. No es particularmente útil saber que SHA-2 es una función hash con construcción Merkle-Damgard si aún no sabes qué es una función hash.

En su nivel más básico, las funciones hash toman entradas de cualquier tamaño y luego las salidas de longitud fija, que se conocen como hash.

Las funciones hash más simples se utilizan para tareas como la recuperación y el almacenamiento de datos. Una de las principales ventajas de estas funciones hash simples es que permite encontrar y acceder a los datos en un período de tiempo corto y constante.

¿Qué son las funciones hash criptográficas?

Las funciones hash criptográficas son tipos especiales de funciones hash que tienen una variedad de propiedades extrañas. No solo cambian los datos de cualquier longitud en valores de longitud fija, sino que también son:

  • Deterministas: esto significa que la misma entrada siempre conduce al mismo hash de longitud fija que su salida. Cuando ingresa, «hashing is complicated» en una calculadora SHA-256 , siempre obtienes un hash de d6320decc80c83e4c17915ee5de8587bb8118258759b2453fce812d47d3df56a.
  • Diseñado para que los cambios leves alteren significativamente la salida: si cambias la entrada inicial aunque sea un poco, terminarás con un hash que parece no tener ninguna relación. Como ejemplo, poniendo «hashing is complicated z » en la misma calculadora hash, obtenemos un hash de 54afff2602d37e8dee0d696d7f6a352e8d1bae481b31cb50622b29b20594c2e5. Como puedes ver, no parece haber ninguna superposición entre este y el hash anterior, a pesar de la sutil diferencia en las entradas.
  • Rápido de calcular: cuando ingresas una entrada en la calculadora SHA-256, el resultado parece surgir instantáneamente (a menos que tengas una conexión a Internet deficiente o un dispositivo más antiguo). Cuando consideres cada uno de los pasos que se llevan a cabo en el algoritmo SHA-2 , te sorprenderás de lo rápido que es todo el proceso.
  • Funciones unidireccionales: si tomaste cualquiera de los dos hashes que te mostramos y aún no conocías las entradas iniciales, sería imposible descubrir una entrada que resulte en cualquiera de estos hashes específicos. Con las técnicas y la tecnología actuales, se considera tan poco práctico descubrir una entrada adecuada solo del hash SHA-2 que gran parte de la seguridad en línea del mundo se basa en la suposición de que estos ataques no son factibles. En este sentido, estas funciones son unidireccionales. Es relativamente fácil tomar una entrada y calcular el hash, pero casi imposible hacer lo contrario.
  • Resistente a colisiones: las funciones hash criptográficas están diseñadas para que sea inviable que dos entradas diferentes den como resultado el mismo hash. Cuando entradas separadas dan como resultado el mismo hash, se conoce como colisión, por lo que la propiedad requerida de estas funciones se conoce como resistencia a la colisión. Si bien hay diferentes entradas que dan como resultado el mismo valor hash, la probabilidad de encontrarlas debe ser casi imposible para que una función hash criptográfica se considere segura. Si el hash de «hashing is complicated» es 54afff2602d37e8dee0d696d7f6a352e8d1bae481b31cb50622b29b20594c2e5, debe ser muy improbable que alguien pueda tropezar con una entrada que resulte en este mismo hash, independientemente del tiempo que le dediquen.

¿Qué es SHA-2?

Ahora que sabes qué es una función hash y que la familia SHA-2 es un subtipo específico conocido como funciones hash criptográficas, podemos entrar en detalles más específicos de SHA-2.

Como hemos mencionado, SHA-2 no es solo una función hash única, sino una familia de seis. Se los conoce colectivamente como SHA-2 porque la familia son los reemplazos de SHA-1, que era solo un algoritmo único. La familia SHA-2 es la siguiente:

  • SHA-224: esta versión de SHA-2 produce un hash de 224 bits. Tiene un tamaño de bloque de 512 bits y la entrada inicial se divide en palabras de 32 bits para su procesamiento. Las variables de inicialización también tienen una longitud de 32 bits, al igual que las constantes, K. Cada bloque de datos pasa por 64 rondas de operaciones antes de que se produzca el hash final (o el hash intermedio, en los casos en que se procesan varios bloques de datos).
  • SHA-256: SHA-256 da como resultado un hash de 256 bits y tiene un tamaño de bloque de 512 bits. La entrada del mensaje se procesa en palabras de 32 bits, mientras que las variables y constantes de inicialización también tienen una longitud de 32 bits. SHA-256 también implica 64 rondas.
  • SHA-384: esta versión produce un hash de 384 bits. Se diferencia de los dos anteriores en que tiene un tamaño de bloque de 1024 bits. También varía en que tiene palabras de 64 bits, variables de inicialización y constantes. En lugar de 64 rondas, requiere 80 rondas de procesamiento para cada bloque de datos del mensaje.
  • SHA-512: SHA-512 da como resultado un hash de 512 bits. Aparte de eso, se parece mucho a SHA-384 en que tiene un tamaño de bloque de 1024 bits, palabras de 64 bits, variables de inicialización de 64 bits y constantes de 64 bits. Sin embargo, las variables de inicialización particulares con las que comienzan son diferentes de las de SHA-384. También implica 80 rondas.
  • SHA-512/224: esta versión es muy parecida a SHA-512, excepto que da como resultado un hash truncado de 224 bits. Esto significa que implica un proceso que es básicamente el mismo, excepto que solo los 224 bits más a la izquierda se toman como hash, mientras que el resto se descarta. El tamaño del bloque también es de 1024 bits, mientras que las palabras, las constantes y las variables de inicialización tienen una longitud de 64 bits. Sin embargo, las variables de inicialización son diferentes de las utilizadas en SHA-512 o SHA-384. SHA-512/224 también requiere 80 rondas para cada bloque de datos del mensaje.
  • SHA-512/256: al igual que SHA-512/224, esta iteración también es similar a SHA-512, excepto que produce un hash truncado de 256 bits al tomar solo los 64 bits más a la izquierda. Tiene un tamaño de bloque de 1.024 bits, así como palabras, constantes y variables de inicialización de 64 bits. SHA-512/256 también tiene su propio conjunto de variables de inicialización. Se trata de 80 rondas.

Historia

Los predecesores de SHA-2 fueron importantes peldaños para llegar al algoritmo actual. El Instituto Nacional de Estándares y Tecnología (NIST) publicó el estándar federal de procesamiento de información (FIPS) 180 en 1993 para lo que ahora llamamos SHA-0 en 1993. Las debilidades en el algoritmo se descubrieron con relativa rapidez, por lo que se revisó y una versión actualizada, SHA-1, fue lanzada en 1995 con FIPS 180-1.

SHA-1 también se especificó en RFC 3174. Fue modelado de cerca en MD4, la cuarta versión del algoritmo hash Message Digest de Ron Rivest.

El hash de SHA-1 tiene solo 160 bits de longitud, lo que comenzó a plantear problemas de seguridad a medida que la tecnología y las técnicas criptográficas mejoraron con el tiempo. Esto llevó al NIST a introducir otra actualización, que se describió en FIPS 180-2 . Este documento establece tres versiones de SHA:

  • SHA-256
  • SHA-384
  • SHA-512

Nos referimos a estos algoritmos como SHA-2. A pesar de las diferentes longitudes de hash, todos tienen el mismo algoritmo subyacente. En 2008, se agregó una versión de 224 bits de SHA-2 con la publicación de FIPS-3, que profundizó en los detalles del algoritmo. SHA-2 se especifica en RFC 4634.

En 2005, NIST anunció su intención de eliminar gradualmente su aprobación para SHA-1 en 2010 debido a la variedad de problemas de seguridad que se habían descubierto.

Poco después, los investigadores publicaron un artículo que mostraba un ataque en el que se podían encontrar dos mensajes separados que daban como resultado el mismo hash SHA-1 en 269 operaciones, que era significativamente menor que las 280 operaciones supuestas anteriormente. Esto demostró que la situación de seguridad de SHA-1 era aún más grave de lo que se pensaba y empujó a la comunidad hacia una mayor adopción de la familia SHA-2.

Aplicaciones

La familia SHA-2 de algoritmos hash son las funciones hash más comunes en uso. SHA-256 está particularmente extendido. Estas funciones hash a menudo están involucradas en los mecanismos de seguridad subyacentes que ayudan a proteger nuestra vida diaria. Puede que nunca lo hayas notado, pero SHA-2 está en todas partes.

Para empezar, SHA-2 está involucrado en muchos de los protocolos de seguridad que ayudan a proteger gran parte de nuestra tecnología:

  • Seguridad de la capa de transporte (TLS): este es uno de los protocolos de seguridad más utilizados. Lo notarás de manera más destacada cuando te conectes a un sitio web que comience con https en lugar de http. La s al final significa seguro, lo que indica que se está utilizando TLS para cifrar los datos entre tu dispositivo y el servidor. Esto hace que SHA-2 sea una parte importante de muchas de las conexiones que realizan sitios web cuando navegan en línea.
  • Seguridad de protocolo de Internet (IPSec): IPSec se usa para asegurar la conexión entre dos puntos y se ve más comúnmente en las VPN.
  • Pretty Good Privacy (PGP): PGP es uno de los protocolos más populares para cifrar correos electrónicos para que solo el destinatario pueda leerlos. Protege los mensajes de piratas informáticos y otras partes que pueden leer los datos, como tu ISP.
  • Extensiones de correo de Internet seguras/multipropósito (S/MIME): S/MIME es otro protocolo de seguridad importante que interviene en el cifrado de correo electrónico.
  • Secure Shell (SSH): SSH se usa más comúnmente para acceder de forma remota a computadoras y servidores, pero también tiene aplicaciones de reenvío de puertos, tunelización y transferencia de archivos.

Además de ser un componente central de los protocolos de seguridad mencionados anteriormente, la familia SHA-2 tiene una variedad de otros usos. Estos incluyen:

  • Autenticación de datos: las funciones hash seguras se pueden usar para demostrar que los datos no se han alterado y están involucradas en todo, desde la autenticación de evidencia hasta la verificación de que los paquetes de software son legítimos.
  • Hashing de contraseñas: las funciones de hash SHA-2 a veces se utilizan para el hash de contraseñas, pero esta no es una buena práctica. Es mejor usar una solución que se adapte al propósito como bcrypt.
  • Tecnologías de bloques: SHA-256 está involucrado en la función de cadena de prueba de trabajo en Bitcoin y muchas otras criptomonedas. También puede participar en proyectos de blockchain de prueba de participación.

Variaciones dentro de la familia SHA-2

Hemos presentado probablemente las seis funciones SHA-2 diferentes y enumerado algunas de las diferencias entre ellas. Ahora es el momento de analizar lo que realmente significan estas diferencias:

Longitud de hash

Los algoritmos anteriores producen cuatro longitudes de hash diferentes:

  • 224 bits
  • 256 bits
  • 384 bits
  • 512 bits

La longitud del hash es la longitud del hash en bits. Un hash de 512 bits es mucho más largo que un hash de 22 bits, de forma similar a como un número de ocho dígitos es mucho más grande que uno de cuatro dígitos.

Como regla general, cuanto menor sea la longitud del hash, más fácil será encontrar una colisión, que es cuando dos entradas separadas dan como resultado el mismo hash. Considerando un hash como un número largo, que básicamente lo son, esto tiene sentido.

Si te dijéramos que estamos pensando en un número que está entre uno y cinco y adivinaras que es cuatro, nadie se impresionaría particularmente. Si te dijéramos que estamos pensando en un número entre uno y un millón y adivinaras correctamente que es 984.287, nos volaría la cabeza.

¿Por qué? Porque es mucho más fácil encontrar una colisión cuando se trata de un rango de números más pequeños. Así como es mucho más fácil adivinar un número entre uno y cinco que adivinar uno entre uno y un millón, es mucho más fácil encontrar una colisión para un hash que está entre cero y:

ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Que es encontrar uno entre cero y:

ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Las «f» son en realidad números, pero están escritas en un sistema conocido como hexadecimal, a diferencia de los números decimales más convencionales que usamos en la vida cotidiana. Los números decimales a los que estás acostumbrado son un sistema de base 10, lo que básicamente significa que hay 10 números diferentes (0, 1, 2, 3, 4, 5, 6, 7, 8 y 9).

Probablemente conozcas otro sistema de numeración, el binario, que es de base 2, lo que significa que solo hay dos opciones en el sistema, 0 o 1. El hexadecimal es un sistema de base 16, lo que básicamente significa que hay 16 números. (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e y f).Esta es la razón por la cual el hash SHA-256 que hemos enumerado varias veces tiene las letras a, b, c, d, e y f.

Ahora, regresemos de nuestra tangente a las longitudes de hash una vez más. Un hash más largo es más resistente a colisiones que uno más corto. A pesar de esto, cada una de las longitudes de hash de la familia SHA-2 se considera segura en la mayoría de las aplicaciones.

La mayor resistencia a la colisión de un hash más largo viene con una compensación. Esto se debe a que cuanto más largo es el hash, más tiempo lleva calcularlo y mayor es la cantidad de recursos computacionales que consumen. A medida que avanza la tecnología, se vuelve más factible encontrar colisiones de hashes más grandes. A su vez, nuestros poderes computacionales también aumentan con el tiempo, por lo que se vuelve más práctico usar hashes más largos y que consumen más recursos.

Tamaño de bloque

El tamaño del bloque también es un compromiso entre seguridad, velocidad y requisitos de recursos. Cuanto más pequeño sea el bloque, más bloques necesitarán para procesar una entrada de datos determinados (si la entrada es mayor que el tamaño de un solo bloque). Sin embargo, estos bloques más pequeños generalmente tendrán un tiempo de cálculo más corto. Hay factores adicionales que intervienen en la determinación del tamaño de bloque más eficiente para un escenario determinado, pero discutir las complejidades del hardware y otros aspectos nos llevaría demasiado por la tangente.

Los tamaños de bloque de 512 y 1024 bits generalmente se consideran seguros, pero las circunstancias individuales de una situación dada pueden llevar a que se elija uno u otro como el tamaño preferido para la implementación. Por lo general, se utilizará el tamaño de bloque mínimo seguro que se adapte al entorno operativo de destino.

Longitud de palabras, variables de inicialización y constantes

Verás que el tamaño del bloque para cada algoritmo de la familia SHA-2 siempre es dieciséis veces el tamaño de la longitud de la palabra.

Esto se debe a que el bloque de relleno de datos de entrada siempre se divide entre 16 palabras (se derivan otras 48 palabras de estas dieciséis en el caso de los algoritmos SHA-2 con tamaño de bloque de 512 bits. Se derivan otras 64 palabras para los algoritmos con tamaño de bloque de 1.024 bits).

Esto significa que las palabras deben ser un dieciseisavo del tamaño del bloque. En el caso de los algoritmos con tamaño de bloque de 512 bits como SHA-224 y SHA-256, cada palabra debe tener una longitud de 32 bits (512/16=32). El resto de la familia tiene un tamaño de bloque de 1024 bits y la longitud de sus palabras es de 64 bits (1024/16=64).

Una de las palabras se procesa en cada ronda, y en cada ronda se mezcla con las ocho variables de inicialización diferentes (después de la ronda 0, las variables recién calculadas se usan en lugar de las variables de inicialización). La constante también se agrega en medio de estas operaciones.

En las versiones de tamaño de bloque de 512 bits del algoritmo (SHA-224 y SHA-256), las palabras, las constantes y las ocho variables de inicialización/funcionamiento independientes utilizadas en cada ronda tienen una longitud de 32 bits. Junto con la ampliación modular, esto garantiza que los resultados de cada operación y cada ronda tendrán siempre la misma longitud constante.

Lo mismo ocurre con los cuatro algoritmos SHA-2 con un tamaño de bloque de 1024 bits, excepto que todos los números tienen una longitud de 64 bits.

La razón para diseñar algoritmos con longitudes de palabra de 32 o 64 bits tiene que ver con la velocidad y el hardware en el que se pretende realizar estos cálculos. Idealmente, el tamaño del registro de la CPU coincidirá con la longitud de la palabra.

Número de rondas

Cada ronda de SHA-2 implica mezclar una parte de la entrada del mensaje (una de las palabras), con las variables de inicialización/funcionamiento y la constante apropiada. Se hace a través de una serie compleja de operaciones.

Como mencionamos anteriormente, uno de los requisitos de una función hash criptográfica segura es que es una función unidireccional, lo que significa que no puedes averiguar la entrada original solo del hash, ni puedes averiguar ninguna entrada que también podría producir el mismo hash.

Para lograr esto, el algoritmo SHA-2 mezcló poderosamente los datos de entrada con las constantes y las variables de inicialización/funcionamiento, de acuerdo con un proceso muy estructurado. En este proceso, cada ronda basta para mezclar aun mas los datos.

Una metáfora para las rondas

Quizás sería útil visualizar lo que sucede en cada ronda a través de una metáfora. Digamos que tienes dos páginas del mismo periódico. Una es la portada y estás realmente interesado en las principales historias. La otra página son solo los clasificados, que no necesitas.

Digamos que en la primera ronda cortas cada página en cien pedazos. Luego tomas una décima parte de las piezas de la portada y las tiras. Los reemplazas con una décima parte de las piezas de las páginas clasificadas y luego las mezclas. Ahora tienes dos montones, uno incluye 100 piezas, que son en su mayoría de la página principal. La otra pila contiene 90 piezas de la página clasificada. Al final de esta ronda, puede que te tome un poco de tiempo, pero probablemente puedas volver a armar gran parte de la primera página y descubrir lo que dicen los titulares si así lo deseas.

En la segunda ronda, vuelves a cortar todos los pedazos de papel en dos. Tiras otra décima parte de las piezas de la pila de la primera página y las reemplazas con la misma cantidad de piezas de la pila clasificada. Ahora tienes 200 piezas de la mayoría de la portada en una pila y 160 piezas de los clasificados en la otra. Te llevaría aún más tiempo ahora, pero probablemente podrías volver a montar gran parte de la página principal. Probablemente aún puedas descifrar los titulares, o al menos ser capaz de inventar otro titular que encaje en los espacios donde faltan las letras.

En la tercera ronda, haces lo mismo una vez más, y terminas con 400 hojas de papel en la pila de la portada, pero ahora el 30 por ciento proviene de los clasificados. En la cuarta ronda, tienes 800 piezas, pero solo el 40 por ciento es de la portada original. Para la quinta ronda son 1.600 y solo el 50 por ciento, mientras que para la sexta se trata de 3.200 piezas, con solo el 40 por ciento de la portada original.

A medida que avanzas, se vuelve más y más difícil volver a armar los titulares, o incluso pensar en un título que se ajusta a las letras restantes.

Esta no es una metáfora perfecta de la forma en que funcionan las funciones hash, pero el punto principal es que con cada ronda, se vuelve más y más difícil volver a ensamblar la entrada original, o incluso encontrar cualquier entrada que encaje. En algún momento, simplemente dirías que no es factible.

El ejemplo anterior se parece mucho a una función hash unidireccional. Los titulares son como las palabras de nuestros datos de entrada que procesamos a través del algoritmo SHA-2. Las constantes y las variables de inicialización son similares a la página de clasificados. En ambos casos, son básicamente datos adicionales sin sentido que se mezclan con la entrada.

Las rondas tanto en nuestra metáfora como en el algoritmo SHA-2 también realizan funciones similares. Sirven para mezclar nuestros datos de entrada con los datos sin sentido. Después de cada ronda, los datos de entrada se mezclan más con los datos sin sentido, lo que hace que sea cada vez más difícil averiguar la entrada inicial o cualquier otra entrada que encaje. Eventualmente, llega al punto en que simplemente no es práctico encontrar una entrada que pueda dar el mismo resultado.

Ten en cuenta que nuestra metáfora produjo una tasa de cambio exponencial después de cada ronda, donde había el doble de piezas al final de cada ronda que al principio. El algoritmo SHA-2 no divide la cantidad de datos al final de cada ronda, ni aumenta la complejidad a un ritmo tan alto con el procesamiento de cada ronda. Si tienes esto en cuenta, y que solo estamos demostrando el concepto en lugar de la tasa de aumento, la metáfora aún debería proporcionar una buena visualización del papel que juegan las rondas en el proceso SHA-2.

Lo principal que estamos tratando de transmitir es que la cantidad de rondas en un algoritmo afecta la factibilidad de averiguar una entrada del hash. Si el algoritmo SHA-2 tuviera solo una ronda de duración, los datos no se habrían mezclado completamente y no sería demasiado difícil encontrar una entrada que se ajuste al hash. Con 64 rondas, se mezcla tanto que no consideramos factible encontrar una entrada coincidente, mientras que 80 rondas nos brindan un margen de seguridad aún mayor.

Truncamiento

SHA-512/224 y SHA-512/256 son casi iguales a SHA-512. Si bien cada uno usa sus propios conjuntos de variables de inicialización, la principal diferencia es que el hash está truncado. Esto significa que solo los 224 (o 256) bits más a la izquierda se eliminan como hash, y los otros 288 (o 256) bits a la derecha se descartan abundantemente.

Este truncamiento hace que SHA-512/224 y SHA-512/256 sean seguros contra ataques de extensión de longitud. Ves estos ataques en aplicaciones donde se agrega un valor secreto a los datos de entrada, que luego se codifica. Estos ataques son una preocupación en situaciones en las que el atacante tiene acceso a los datos de entrada, pero no al valor secreto.

Si se utilizan algoritmos vulnerables como MD5, SHA-1, SHA-256 o SHA-512 en el hash, es posible que se produzcan ataques de extensión de longitud. El atacante necesitaría saber:

  • Qué algoritmo hash se está utilizando.
  • La entrada de datos de la victima.
  • El hash de la entrada de datos de la victima.

Si el atacante tiene esta información, es posible que pueda reproducir una firma sin haber conocido el valor secreto.

Este ataque puede parecer un poco abstracto, así que vemos un escenario en el que esto podría ser problemático. Imagina una situación en la que un servidor autentique a un cliente en función de esta firma. La firma es un sustituto del valor secreto, que obviamente el cliente no quiere compartir con el servidor, ya que podría exponer el valor secreto.

Si el ataque de extensión de longitud permite que un atacante reproduzca esta firma sin haber conocido el valor secreto, por lo tanto, permite que el atacante se autentique de manera fraudulenta. De esta manera, los algoritmos de hashing que son vulnerables a los ataques de extensión de longitud pueden resultar en que se socave la seguridad proporcionada por el valor secreto.

Ahora que hemos cubierto los conceptos básicos de los ataques de extensión de longitud, podemos sumergirnos en cómo prevenir el truncamiento. Los ataques de extensión de longitud requieren el hash de la entrada de datos de la víctima para calcular la firma. Los hashes truncados como los producidos por SHA-512/224 y SHA-512/256 no contienen suficiente información, porque las salidas no contienen los 288 (o 256 bits) más a la derecha.

Aunque SHA-512/224 y SHA-512/256 no son particularmente comunes en este momento, su resistencia a los ataques de extensión de longitud es una ventaja significativa. Si se va a implementar una función hash SHA-2 en una situación en la que estos ataques son posibles, cualquiera de estos dos algoritmos puede ser la opción más segura.

Diseño del algoritmo SHA-2

Ahora que hemos cubierto las diferencias entre estas variaciones de SHA-2, es hora de ver el diseño general de estas funciones hash. Para empezar, se construyen a partir de funciones de compresión unidireccionales.

Funciones de compresión unidireccional de SHA-2

En criptografía, las funciones de compresión unidireccionales toman dos entradas de longitud fija y producen una salida que también es de longitud fija. El proceso no puede averiguar las dos entradas si solo tiene acceso a la salida. Las entradas no tienen por qué tener la misma longitud, como veremos en SHA-2.

Estas funciones de compresión unidireccionales no deben confundirse con los algoritmos de compresión que usamos para reducir el tamaño de los archivos de audio, video y otros.

Para cada bloque de datos que procesa SHA-256, la función de compresión unidireccional tiene entradas de:

  • 512 bits de datos de mensajes : SHA-2 procesa un bloque de datos a la vez. Esta entrada actúa de manera similar a como lo haría una clave en un bloqueador de bloque normal. Con esto, queremos decir que juega un papel de control en lo que será la salida. Si hay más de un bloque de datos que debe procesarse, estos bloques posteriores se personalizarán en las entradas una vez que el primer bloque de datos ha pasado por el algoritmo SHA-2. El bloque final siempre debe estar acolchado.
  • Un conjunto de variables de inicialización de 256 bits: se dividen en ocho partes para el procesamiento inicial del primer bloque. Si hay más de un bloque, el hash intermedio de 256 bits cumple el rol de las variables de inicialización en cada una de estas rondas. Estas variables de inicialización y hash intermedios reemplazan el texto sin formato que se cifraría en un bloqueador de bloque normal.
  • Un hash de 256 bits: para un solo bloque de datos, la salida de la función de compresión es el hash de 256 bits. Al procesar múltiples bloques de datos, cada bloque produce un hash intermedio de 256 bits. Como mencionamos anteriormente, estas actúan como entradas para el siguiente bloque. Cuando se han procesado todos los bloques, la salida del bloque final es el hash de 256 bits.

Ten en cuenta que las funciones de compresión en SHA-384, SHA-512, SHA-512/224 y SHA-512/256 tienen entradas de:

  • 1.024 bits de datos de mensajes.
  • Un conjunto de variables de inicialización de 512 bits o un hash intermedio de 512 bits.

Ellos emiten hashes de 384, 512.224 o 256 bits, según el algoritmo. En el caso de que se procesen varios bloques, los hashes intermedios son de 512 bits.

Funciones de compresión Davies-Meyer

La función de compresión unidireccional particular que hemos estado discutiendo es un subtipo conocido como función de compresión de Davies-Meyer. La característica definitoria es la flecha que va desde el H i-1 directamente al círculo rojo con la cruz en él.

Esto representa la adición modular, donde las variables de inicialización (o el hash intermedio del bloque de datos anterior) se agregan a la salida de E. No todas las funciones de compresión unidireccional tienen esta característica.

Esta estructura de Davies-Meyer tiene varias ventajas sobre alternativas como Miyaguchi-Preneel. De las otras alternativas principales, es una de las opciones más simples. También permite que el tamaño del bloque sea diferente al tamaño de la entrada del mensaje sin necesidad de otras adiciones al algoritmo. La estructura de Davies-Meyer también le da al algoritmo SHA-2 algunos beneficios de eficiencia.

Construcción Merkle-Damgard

Las funciones de compresión unidireccional de la familia SHA-2 se organizan de acuerdo con la construcción Merkle-Damgard, que es un diseño de función hash criptográfica específica. El objetivo de la construcción de Merkle-Damgard es hacer que la función hash sea resistente a colisiones, lo que significa que es inviable para un atacante encontrar dos entradas separadas que puedan producir el mismo hash.

Por qué es importante la resistencia a la colisión en la construcción Merkle-Damgard

Las colisiones son preocupantes, porque los hashes a menudo se usan para firmas digitales y otros procesos de autenticación. Si un atacante puede encontrar colisiones donde dos entradas separadas dan como resultado el mismo hash, esto abre la posibilidad de que se autentique de manera fraudulenta.

Un ejemplo involucra a un atacante que construye cuidadosamente dos contratos que dan como resultado el mismo hash, uno que es legítimo y otro que es fraudulento. Luego, el atacante le mostraría el contrato legítimo a su jefe y le pediría que lo firmara digitalmente. Dado que el documento es legítimo, el jefe lo firmaría con su firma digital, que se basa en el hash del documento más la clave privada del jefe.

El atacante cambiaría entonces el contrato bueno por el fraudulento y lo enviaría junto con la firma digital al abogado de su jefe. El contrato fraudulento podría estipular que el jefe ceda los derechos de la casa del jefe al empleado. Luego, el abogado revisaría el contrato y verificaría la firma digital. Debido a la travesura del empleado, la firma digital coincide. Parecería como si el jefe hubiera firmado digitalmente el contrato, por lo que el abogado pensaría que es legítimo y comenzaría el proceso de entregar los derechos legales de la casa al empleado.

Por supuesto, el documento original que utilizó el jefe habría sido algo completamente diferente, y la única razón por la que parece legítima es porque la función hash involucrada en el proceso de firma digital no era resistente a colisiones.

El ejemplo anterior es un poco extremo, pero el punto es que las colisiones socavan por completo la seguridad de nuestros sistemas de autenticación, por lo que debemos diseñar cuidadosamente nuestras funciones hash para evitarlas.

¿Cómo funciona la construcción Merkle-Damgard?

La construcción Merkle-Damgard implica funciones de compresión, que solo pueden manejar entradas fijas. Si la función de compresión está diseñada para manejar 512 bits de datos a la vez, no puedes enviar simplemente 73 bits o 1427 bits directamente a través de ella. Debes rellenar los datos para que ocupen los 512 bits completos, o dividir los datos en varios bloques y luego agregar el relleno necesario para completar el bloque final. Ten en cuenta que solo el último bloque requiere relleno.

El primer paso importante es agregar relleno a los datos de entrada de nuestros mensajes para asegurarnos de que los tamaños de nuestros bloques están todos 512 – bits de largo.

Los últimos 64 bits del bloque se reservan para agregar la longitud del mensaje, esto se debe a que es una parte crítica de la construcción de Merkle-Damgard.

Esto se conoce como relleno de longitud o refuerzo de Merkle-Damgard, y sirve para demostrar que solo se puede encontrar una colisión en la función hash general si se puede encontrar una colisión dentro de la función de compresión. Recuerda, las colisiones son malas y SHA-2 es una función hash que se construye con funciones de compresión. Esencialmente, lo que dice la prueba es que mientras las funciones de compresión unidireccionales sean resistentes a colisiones, también podemos estar seguros de que la función hash general también es resistente a colisiones.

La prueba subyacente involucra un poco de matemática, pero básicamente muestra que podemos tener esta propiedad en nuestras funciones hash si el esquema de relleno da como resultado que un bloque de mensaje relleno nunca sea el final de otro. Agregar la longitud como relleno al final del bloque final de la entrada evita que esto suceda y, en última instancia, nos ayuda a probar la seguridad de la función hash.

Puede ser más fácil entender la construcción de Merkle-Damgard si pretendemos que los datos de nuestro mensaje en realidad tienen tres bloques de largo.

El cifrado de bloque SHA-2

Hemos discutido las funciones de compresión de Davies-Meyer que se organizan en la construcción de Merkle-Damgard para formar la estructura general de la familia de algoritmos SHA-2. Ahora, es hora de acercar un poco y mirar los teclados de bloque a partir de los cuales se construye la función de compresión.

Un bloqueado de bloque se usa más típicamente en el bloqueado e implica:

  • Una entrada: este suele ser el texto sin formato que debe cifrarse.
  • Una clave: un valor secreto que se supone que solo conocen aquellos que están autorizados para cifrar y descifrar el texto sin formato.
  • Una salida: los datos pueden grabarse, que solo se leer una vez que se han descifrado con la clave.

Si bien las funciones de hash en realidad no implican nada parecido al descifrado, el proceso de hash tiene algunas similitudes con el grabado. La función de compresión de Davies-Meyer convierte dos valores de entrada (uno puede verso como texto sin formato, mientras que el otro puede verse como la clave) y produce una salida única, que parece mucho al texto grabado.

¿SHA-2 es seguro?

La familia de algoritmos SHA-2 generalmente se considera segura, por lo que se recomienda para la mayoría de las aplicaciones donde se necesita un algoritmo hash seguro. Cada uno de los seis algoritmos es seguro en la mayoría de los escenarios, sin embargo, puede haber ciertos casos en los que algunos sean preferibles a los demás.

Como ejemplo, si los ataques de extensión de longitud son una amenaza, puede ser mejor optar por SHA-512/224 o SHA-512/256, como discutimos en la sección Truncamiento de este artículo.

Se han realizado importantes investigaciones sobre la seguridad de la familia SHA-2 a lo largo de los años y no se han presentado problemas importantes. Como ejemplo de la confianza de la comunidad académica en estos algoritmos, en 2016 los investigadores publicaron un artículo que demostró los mejores ataques que podrían manejar.

En los casos de SHA-512, SHA-512/224 y SHA-512/256, puedes encontrar colisiones solo en versiones reducidas de 27 rondas de estos algoritmos. Esto está muy por debajo de las 80 rondas que realmente usan, lo que significa que todavía hay un gran margen de seguridad y no tenemos que preocuparnos demasiado por su seguridad en este momento. Los otros miembros de la familia SHA-2 también tienen importantes márgenes de seguridad.

Alternativas a SHA-2

El Instituto Nacional de Estándares y Tecnología lanzó una familia de algoritmos más segura en 2015. Conocidos como SHA-3, generalmente se consideran más seguros que la familia SHA-2.

Sin embargo, ha habido una aceptación limitada de la familia SHA-3, porque simplemente no hay mucha necesidad de cambiar todavía. Como mencionamos, los algoritmos SHA-2 todavía tienen un gran margen de seguridad, por lo que no hay mucha fuerza que incite a las instituciones a actualizar sus algoritmos hash.

Es bueno tener SHA-3 en nuestro bolsillo trasero, para que tengamos un conjunto de algoritmos para cambiar cuando sea el momento adecuado. Esto debería ayudar a garantizar una transición sin problemas. Sin embargo, simplemente no hay mucha necesidad de dar ese salto en el futuro previsible.

En este momento, SHA-2 es el estándar de la industria para algoritmos hash, aunque SHA-3 puede eclipsar esto en el futuro. Durante el lanzamiento de SHA-3, la mayoría de las empresas estaban en medio de la migración de SHA-1 a SHA-2, por lo que cambiar directamente a SHA-3 mientras SHA-2 aún era muy seguro no tenía sentido. Junto con esto, SHA-3 fue visto como más lento que SHA-2, aunque este no es exactamente el caso. SHA-3 es más lento en el lado del software, pero es mucho más rápido que SHA-1 y SHA-2 en el lado del hardware, y cada año es más rápido. Por estas razones, es probable que veamos el cambio a SHA-3 más adelante, una vez que SHA-2 se vuelva inseguro o obsoleto.