viernes, octubre 02, 2020

Raspberry Pi Random Numbers Beacon: Una baliza de números aleatorios del mundo Maker para el mundo IoT #IoT #Criptografía #makers #RaspberryPi

Antes de empezar, quiero aclarar que este no es un artículo sobre la teoría de los números aleatorios de los muchos que podéis encontrar por Internet ;). Esta vez nos centraremos en lo práctico, es decir, implementar nuestro propio generador de números aleatorios lo más “verdadero” posible (luego veremos un poco más este término) utilizando hardware asequible, en este caso una Raspberry Pi.

Figura 1: Raspberry Pi Random Numbers Beacon:
Una baliza de números aleatorios del mundo Maker para el mundo IoT

Por cierto, si queréis encontrar más proyectos enfocados a la ciberseguridad usando este mismo hardware, en el libro “Raspberry Pi para Hackers & Makers: PoC & Hacks Just for Fun” de la editorial 0xWord podéis encontrar varios de ellos:

Figura 2: Libro de Raspberry Pi para hackers & Makers
PoCs & Hacks Just for Fun en 0xWord escrito por
Pablo Abel Criado, Hector Alonso y Amador Aparicio

Los números aleatorios son un elemento fundamental dentro del mundo de la ciberseguridad, y sobre todo en criptografía. Pero no sólo en criptografía son importantes los números aleatorios. También lo son por ejemplo en la secuencia de números para TCP/IP, TLS, ASLR offsets, Salts, DNS, etcétera. Volviendo de nuevo a la criptografía, estos se utilizan principalmente para obtener cifrados seguros. Pero estos números aleatorios, a pesar de lo que podamos pensar, no son sencillos de generarlos digamos, de manera 100% random

Números aleatorios, un breve repaso 

Generar un número aleatorio con un ordenador u otro dispositivo que sea capaz de hacer los cálculos, puede que, debido a su naturaleza, ese número no sea tan aleatorio o incluso se abre la posibilidad de llegar a predecirlo. Y esto puede comprometer la seguridad del cifrado y, por lo tanto, de todo el sistema. La calidad de un número aleatorio define en un alto porcentaje la fortaleza del cifrado final. 

Figura 3: Representación en imágenes de los números aleatorios. A la izquierda, números aleatorios reales y a la derecha podemos observar los patrones de repetición en otro generador. 

Dicho de otra manera, la calidad del número aleatorio obtenido con un generador influye directamente en la dificultad de atacar cualquier tipo de sistema que use algún tipo de cifrado. La mayoría de los algoritmos se basan en cómo un atacante es capaz de adivinar (o predecir) cierto número de bits que se utilizaron en la clave original. 


Y aquí es donde radica la importancia de los números aleatorios, si el atacante no tiene información por donde empezar (ya que es aleatoria) el porcentaje de éxito para romper el sistema se reduce prácticamente a cero. En definitiva, sin aleatoriedad, todas las operaciones de criptografía se podrían predecir y por ello, dichas operaciones o transacciones serían inseguras.

Pseudo-Random

La mayoría de las librerías que podemos utilizar en un ordenador, generan los números llamados Pseudo-Random (PRNG, pseudo random number generators) o casi-aleatorios. La mayoría de ellos son creados por un proceso determinista (es decir, los números se generan con una misma base y existen posibilidades de repetir el patrón) lo que implica que al final, no son realmente tan aleatorios. La Figura 3 muestra perfectamente ese hecho. 

Para muchas aplicaciones esto no es en sí un problema, pero en ciberseguridad es vital siempre mejorar la precisión de la semilla (seed). Por lo tanto, es importante obtener mejor precisión a la hora generar estos números ya que son la base que se utiliza como entrada al algoritmo de cifrado. Muchos sistemas operativos llevan incluidos un PRNG implementados por software (en este enlace del blog de LUCA podéis obtener más información sobre cómo generarlos).

Ya sabemos que en Linux cuando generamos una clave criptografía, a la hora de generar la semilla se nos pide teclear algo o mover el ratón. De esta forma generamos la suficiente entropía (la manera en la que podemos medir la incertidumbre o el desorden de cualquier sistema) y por lo tanto obtener así el mejor resultado aleatorio posible para nuestra semilla. El problema es que esta entropía se recolecta de la misma manera en todos los sistemas operativos Linux y, por lo tanto, en cierto modo es teóricamente predecible. 

True Random

Por otro lado, la generación de números aleatorios denominados True Random (TRNG) se basa principalmente en la obtención de datos de fenómenos físicos, como por ejemplo, temperatura, luz, radioactividad, radio e incluso fenómenos cuánticos (aquí tienes un ejemplo) de los cuales obtenemos una salida no determinista. Otra característica que los define es que no son periódicos en su naturaleza, es decir, no podremos obtener nunca la misma salida, aunque la semilla sea la misma en el mismo generador. 



Este factor es importante ya que marca la diferencia y ofrece diversas técnicas matemáticas para conseguirlo. En el mercado existen una gran variedad de hardware (HRNG) que intentan de mayor o menor manera, conseguir los TRNG lo más preciso posible. El rango de precios puede variar desde los 50€ hasta más de 1.000€


Intel por ejemplo, incluye un TRNG en sus procesadores desde Ivy Bridge, aunque hay discusiones sobre si es TRNG o PRNG. Todos ellos se basan en medir fenómenos cuánticos o de naturaleza, pero siempre son valores out-of-the-box, es decir, aquellos que ocurren alrededor del dispositivo.

Raspberry Pi Random Number Generator Beacon

Como antes hemos comentado, nuestro objetivo para esta PoC es construir una especie de baliza (beacon) que esté continuamente generando números aleatorios y los presente realizando simplemente peticiones HTTP a la dirección IP o URL del dispositivo. De esta forma, cuando un usuario o un dispositivo necesite un número aleatorio, con hacer esa llamada recibirá uno distinto cada vez que se realice la solicitud. 

Como base de esta PoC hemos utilizado dos componentes fundamentales, una Raspberry Pi, un shield llamado Sense Hat, el cual nos ofrece una gran cantidad de sensores, pero además hemos añadido una cámara típica de Raspberry Pi para obtener más mediciones, como ahora veremos. 


Con el Sense Hat tendremos la posibilidad de leer valores como temperatura, humedad, presión atmosférica, acelerómetro y giróscopo. Además, incluye un display led de varios colores y un pequeño joystick que, en principio, no usaremos en este proyecto (aunque este podría servir como una entrada más de datos aleatorios). 

Figura 9: Aspecto final del Raspberry Pi Random Number Generator Beacon. 

En total, para generar toda la entropía necesaria y así obtener un número lo más aleatorio cercano a los TRN, vamos a utilizar los siguientes sensores para recibir los datos del exterior:

1. Cámara
2. Giróscopo (x,y,z)
3. Acelerómetro
4. Magnetómetro
5. Temperatura
6. Humedad
7. Presión

La cámara realiza una foto y a partir de ella genera una serie de valores que siempre serán distintos en función de donde esté enfocando (por ejemplo, a una ventana es perfecto ya que las variaciones, por ejemplo, de luminosidad, nos servirán para obtener información lo más aleatoria posible. Una vez tomada la foto, obtenemos su hash utilizando la librería ImageHash el cual pasamos a su vez a base64

El resto de los valores obtenidos de las diferentes lecturas de los sensores, se almacenarán igual, en base64. Una vez obtenidos todos los datos, convertimos la información a binario y realizamos una serie de operaciones XOR entre las diferentes entradas también de forma aleatoria.

Finalmente, obtenemos un número aleatorio codificado como ya hemos comentado en base64. Pero para añadir aún más entropía, de cada valor leído por cada sensor, utilizaremos sólo los primeros 32 bits de cada uno de ellos. Estos trozos los reordenamos de forma aleatoria para componer finalmente un nuevo número basado en esas diferentes partes. El siguiente esquema explica en detalle el funcionamiento descrito:

Figura 10: Esquema de funcionamiento desde la lectura de los datos
de los sensores hasta la generación del número final. 

Obviamente esta secuencia se puede perfeccionar de muchas maneras, como por ejemplo evitando usar números random (generados por la Raspberry Pi, podría conseguirlo de otra manera por ejemplo usando los datos de un sensor o varios) para el primer XOR y también para la ubicación (1 y 3) entre otros cambios posibles. Pero el objetivo de este proyecto no es montar un generador comercial de números aleatorios verdaderos, sino experimentar con él y aproximarnos lo máximo posible a ellos.

Figura 11: Salida de ejecución del código que levanta el servidor
web en Flask y genera los números aleatorios. 

En resumen, esta puede ser una buena plataforma para comenzar a investigar otros métodos de obtención de dichos números aleatorios usando hardware relativamente barato. Por cierto, existen sensores muchos más asequibles que el Sense Hat o directamente podemos utilizar un breadboard y montarlos individualmente allí, pero esta opción la he elegido simplemente porque la tenía por casa ;) y además incluye una gran colección de sensores que podemos utilizar fácilmente con su librería.

Recibiendo los números generados

Para recibir los números aleatorios generados por la Raspberry Pi Beacon, hemos creado un pequeños servidor web basado en Flask el cual será el responsable de enviar el número aleatorio generado a través de HTTP. Por ejemplo, con el comando curl podríamos acceder al número aleatorio generado en ese momento de la petición:
$ curl 192.168.2.230
mMeyNFZDuPG9TQHlGvoVQ0NFiFc=%

$ curl 192.168.2.230
4eGAtQv/AON9imQ98iNZuzfElPY=%

$ curl 192.168.2.230
2N0tdUtTCqRaMPPudE0Ecb/W+lM=%
O también dese el navegador web:

Figura 12: Número aleatorio generado accesible
vía web usando el navegador Safari. 

Un posible escenario práctico para esta PoC se podría situar dentro del mundo del IoT. Muchos dispositivos en el Internet of Things están continuamente generando claves de cifrado tanto para transmisiones como para proteger la información que se encuentra almacenada en ellos. En el siguiente vídeo se puede ver todo el proceso, así como el funcionamiento interno del servidor web. 


Figura 13: Raspberry Pi Beacom: Random Number Generator

Por ejemplo, en ese entorno IoT podríamos usar nuestro Raspberry Pi Beacon para obtener los números aleatorios necesarios en intervalos de tiempo hacia dispositivos IoT y de esta forma conseguir nuevas claves de cifrado en todos nuestros aparatos. Eso sí, previamente habría que cifrar el acceso al servidor web o incluso los números obtenidos, pero eso ya es otra historia ;) 

Conclusión 

En definitiva, hoy día disponemos de una gran variedad de hardware a precio asequible el cual podemos utilizar para proyectos similares al que exponemos hoy aquí. La potencia de algunos de estos elementos nos permite explorar su funcionamiento si estar demasiado alejados de productos comerciales que hacen la misma función. Y todo esto gracias al movimiento Maker, que ya sabéis que a nosotros nos gusta, y mis compañeros tienen el libro de Arduino para Hackers: PoCs & Hacks Just for Fun.

Figura 14: "Arduino para Hackers: PoCs & Hacks Just for Fun"

Por cierto, si os interesa el tema de los números aleatorios es indispensable acceder a la web de Random.org, la cual está repleta de recursos relacionados con los ellos.  Gracias a Marta Vila y a Enrique Blanco por sus consejos a la hora de implementar las diferentes combinaciones que conforman el número aleatorio final. 

Happy Hacking Hackers!!!

Fran Ramírez, (@cyberhadesblog) es investigador de seguridad y miembro del equipo de Ideas Locas en CDO en Telefónica, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps", también de "Machine Learning aplicado a la Ciberseguridad” además del blog CyberHades. Puedes contactar con Fran Ramirez en MyPublicInbox.

Figura 15: Contactar con Fran Ramírez en MyPublicInbox

No hay comentarios:

Publicar un comentario