
En criptografía , un ataque de temporización es un ataque de canal lateral en el que el atacante intenta comprometer un sistema criptográfico analizando el tiempo que tarda en ejecutarse un algoritmo criptográfico. Cada operación lógica en una computadora requiere tiempo para ejecutarse, y este tiempo puede variar según la entrada; con mediciones precisas del tiempo de cada operación, un atacante podría reconstruir la información de entrada.
La información puede filtrarse de un sistema mediante la medición del tiempo de respuesta a ciertas consultas. La utilidad de esta información para un atacante depende de diversas variables, como el diseño del sistema criptográfico, la CPU que lo ejecuta, los algoritmos utilizados, detalles de implementación, contramedidas contra ataques de temporización y la precisión de las mediciones. Cualquier algoritmo con variación temporal dependiente de los datos es vulnerable a ataques de temporización. Eliminar estas dependencias temporales es difícil, ya que la variación en el tiempo de ejecución puede ocurrir en cualquier nivel.
La vulnerabilidad a los ataques de temporización suele pasarse por alto en la fase de diseño y puede introducirse involuntariamente mediante optimizaciones del compilador . Las contramedidas incluyen el uso de funciones de ocultación y de tiempo constante .
Desafíos de tiempo constante
Muchos algoritmos criptográficos pueden implementarse (o enmascararse mediante un proxy) de forma que se reduzca o elimine la información de tiempo dependiente de los datos, lo que se conoce como algoritmo de tiempo constante . Una implementación trivial " segura en cuanto a tiempo" puede encontrarse aquí. [ 1 ] Imagine una implementación en la que cada llamada a una subrutina siempre regresa exactamente después de que haya transcurrido un tiempo T , donde T es el tiempo máximo que tarda en ejecutarse esa rutina en cada posible entrada autorizada. Dicha implementación hipotética no filtraría información sobre los datos suministrados a esa invocación (en realidad, las variaciones de tiempo no dependientes de los datos son inevitables). La desventaja de este enfoque es que el tiempo utilizado para todas las ejecuciones se convierte en el del peor caso de rendimiento de la función. [ 2 ] Parecería que se debería aplicar el enmascaramiento para evitar la vulnerabilidad a los ataques de tiempo.
La dependencia de los datos en cuanto a la sincronización puede derivarse de uno de los siguientes factores: [ 3 ]
- Acceso a memoria no local, ya que la CPU puede almacenar los datos en caché. El software que se ejecuta en una CPU con caché de datos presentará variaciones de temporización dependientes de los datos como resultado de las búsquedas en la caché.
- Saltos condicionales . Las CPU modernas intentan ejecutar de forma especulativa saltos condicionales anteriores mediante conjeturas. Una conjetura errónea (algo frecuente con datos secretos prácticamente aleatorios) conlleva un retraso considerable mientras la CPU intenta retroceder. Esto requiere escribir código sin bifurcaciones .
- Algunas operaciones matemáticas "complicadas", dependiendo del hardware de la CPU:
- La división entera casi siempre requiere un tiempo variable. La CPU utiliza un bucle de microcódigo que emplea una ruta de código diferente cuando el divisor o el dividendo son pequeños.
- Las CPU sin mecanismo de desplazamiento de barril ejecutan los desplazamientos y rotaciones en bucle, una posición a la vez. Por lo tanto, la cantidad a desplazar no debe ser un secreto.
- Los procesadores más antiguos realizan las multiplicaciones de forma similar a la división.
Ejemplos
El tiempo de ejecución del algoritmo de elevación al cuadrado y multiplicación utilizado en la exponenciación modular depende linealmente del número de bits '1' en la clave. Si bien el número de bits '1' por sí solo no proporciona información suficiente para encontrar la clave fácilmente, las ejecuciones repetidas con la misma clave y diferentes entradas pueden utilizarse para realizar un análisis de correlación estadística de la información de tiempo y recuperar la clave por completo, incluso por un atacante pasivo. Las mediciones de tiempo observadas a menudo incluyen ruido (proveniente de fuentes como la latencia de la red o las diferencias de acceso a la unidad de disco entre accesos, y las técnicas de corrección de errores utilizadas para recuperarse de errores de transmisión). No obstante, los ataques de tiempo son factibles contra varios algoritmos de cifrado, incluidos RSA , ElGamal y el Algoritmo de Firma Digital .
En 2003, Boneh y Brumley demostraron un ataque práctico de temporización basado en la red contra servidores web con SSL habilitado, aprovechando una vulnerabilidad relacionada con el uso de RSA y optimizaciones del teorema chino del resto . La distancia real de la red en sus experimentos era pequeña, pero el ataque logró recuperar la clave privada de un servidor en cuestión de horas. Esta demostración propició la implementación y el uso generalizado de técnicas de enmascaramiento en las implementaciones de SSL. En este contexto, el enmascaramiento tiene como objetivo eliminar las correlaciones entre la clave y el tiempo de cifrado. [ 4 ] [ 5 ]
Algunas versiones de Unix utilizan una implementación relativamente costosa de la función de la biblioteca `crypt` para convertir una contraseña de 8 caracteres en una cadena de 11 caracteres mediante hash. En hardware antiguo, este cálculo tardaba un tiempo considerable y medible: hasta dos o tres segundos en algunos casos. El programa de inicio de sesión en las primeras versiones de Unix ejecutaba la función `crypt` solo cuando el sistema reconocía el nombre de usuario. Esto filtraba información sobre la validez del nombre de usuario, incluso cuando la contraseña era incorrecta. Un atacante podía explotar estas vulnerabilidades aplicando primero la fuerza bruta para generar una lista de nombres de usuario válidos y, a continuación, intentando acceder combinando solo estos nombres con un gran conjunto de contraseñas de uso frecuente. Sin información sobre la validez de los nombres de usuario, el tiempo necesario para ejecutar este método aumentaría exponencialmente, lo que lo haría prácticamente inútil. Las versiones posteriores de Unix han corregido esta vulnerabilidad ejecutando siempre la función `crypt`, independientemente de la validez del nombre de usuario.
Dos procesos que, de otro modo, estarían aislados de forma segura y se ejecutan en un único sistema con memoria caché o memoria virtual , pueden comunicarse provocando deliberadamente fallos de página o de caché en un proceso y, a continuación, monitorizando los cambios resultantes en los tiempos de acceso del otro. Del mismo modo, si una aplicación es de confianza, pero su paginación o almacenamiento en caché se ve afectada por una lógica de ramificación, una segunda aplicación podría determinar los valores de los datos en comparación con la condición de ramificación mediante la monitorización de los cambios en los tiempos de acceso; en casos extremos, esto podría permitir la recuperación de bits de claves criptográficas. [ 6 ] [ 7 ]
Los ataques Meltdown y Spectre de 2017 , que obligaron a los fabricantes de CPU (incluidos Intel, AMD, ARM e IBM) a rediseñar sus procesadores, se basan en ataques de temporización. [ 8 ] A principios de 2018, casi todos los sistemas informáticos del mundo se vieron afectados por Spectre. [ 9 ] [ 10 ] [ 11 ]
En 2018, muchos servidores de internet seguían siendo vulnerables a ligeras variaciones del ataque de temporización original contra RSA, dos décadas después de que se descubriera la vulnerabilidad original. [ 12 ]
Algoritmos de comparación de cadenas
El siguiente código C demuestra una comparación de cadenas insegura típica que detiene la prueba tan pronto como un carácter no coincide. Por ejemplo, al comparar "ABCDE"con "ABxDE", devolverá después de 3 iteraciones del bucle:
#include <stddef.h>bool insecure_string_compare ( const void * a , const void * b , size_t length ) { const char * ca = a , * cb = b ; for ( size_t i = 0 ; i < length ; i ++ ) if ( ca [ i ] != cb [ i ]) return false ; return true ; }En comparación, la siguiente versión se ejecuta en tiempo constante probando todos los caracteres y utilizando una operación bit a bit para acumular el resultado:
#include <stddef.h>bool constant_time_string_compare ( const void * a , const void * b , size_t length ) { const char * ca = a , * cb = b ; bool result = true ; for ( size_t i = 0 ; i < length ; i ++ ) result &= ca [ i ] == cb [ i ]; return result ; }En el mundo de las funciones de la biblioteca C, la primera función es análoga a , mientras que la segunda es análoga a y de memcmp()NetBSD consttime_memequal()o [ 13 ] de OpenBSD . En otros sistemas, se puede utilizar la función de comparación de bibliotecas criptográficas como OpenSSL y libsodium .timingsafe_bcmp()timingsafe_memcmp
Notas
Los ataques de temporización son más fáciles de realizar si el adversario conoce los detalles internos de la implementación del hardware, y aún más si conoce el sistema criptográfico en uso. Dado que la seguridad criptográfica nunca debería depender de la opacidad de ninguno de estos elementos (véase seguridad por medio de la opacidad , específicamente la máxima de Shannon y el principio de Kerckhoffs ), la resistencia a los ataques de temporización tampoco debería depender de ello. En cualquier caso, se puede adquirir un ejemplar y aplicar ingeniería inversa. Los ataques de temporización y otros ataques de canal lateral también pueden ser útiles para identificar, o posiblemente aplicar ingeniería inversa, un algoritmo criptográfico utilizado por algún dispositivo.
Véase también
Referencias
- ↑ "timingsafe_bcmp" . Consultado el 11 de noviembre de 2024 .
- ↑ "Guía para principiantes sobre criptografía de tiempo constante" . Consultado el 9 de mayo de 2021 .
- ↑ "Criptografía de tiempo constante" . BearSSL . Consultado el 10 de enero de 2017 .
- ↑ David Brumley y Dan Boneh. Los ataques de temporización remota son prácticos. Simposio de Seguridad de USENIX, agosto de 2003.
- ↑ Kocher, Paul C. (1996). "Ataques de temporización en implementaciones de Diffie-Hellman, RSA, DSS y otros sistemas" . En Koblitz, Neal (ed.). Avances en criptología — CRYPTO '96 . Lecture Notes in Computer Science. Vol. 1109. Berlín, Heidelberg: Springer. pp. 104–113 . doi : 10.1007/3-540-68697-5_9 . ISBN 978-3-540-68697-2.
- ↑ Véase Percival, Colin, Cache Missing for Fun and Profit , 2005.
- ↑ Bernstein, Daniel J., Ataques de temporización de caché en AES , 2005.
- ↑ Horn, Jann (3 de enero de 2018). "Lectura de memoria privilegiada con un canal lateral" . googleprojectzero.blogspot.com.
- ↑ "Preguntas frecuentes sobre los sistemas Spectre" . Meltdown y Spectre .
- ↑ "Las fallas de seguridad ponen en riesgo prácticamente todos los teléfonos y computadoras" . Reuters . 4 de enero de 2018.
- ↑ "Impacto potencial en los procesadores de la familia POWER" . Blog de IBM PSIRT . 14 de mayo de 2019.
- ↑ Kario, Hubert. "El ataque de Marvin" . people.redhat.com . Consultado el 19 de diciembre de 2023 .
- ↑ "Consttime_memequal" .
Lecturas adicionales
- Lipton, Richard ; Naughton, Jeffrey F. (marzo de 1993). "Adversarios cronometrados para el hashing". Algorithmica . 9 (3): 239– 252. doi : 10.1007/BF01190898 . S2CID 19163221 .
- Reparaz, Oscar; Balasch, Josep; Verbauwhede, Ingrid (marzo de 2017). "¿Amigo, mi código es de tiempo constante?" (PDF) . Conferencia y Exposición de Diseño, Automatización y Pruebas en Europa (DATE), 2017. págs. 1697–1702 . doi : 10.23919/DATE.2017.7927267 . ISBN 978-3-9815370-8-6. S2CID 35428223 . Describe dudect , un programa sencillo que mide el tiempo de ejecución de un fragmento de código con diferentes datos.
- Ataques de canal lateral