El algoritmo de dónde votar

2

Dentro del proceso independentista que envuelve estos días la actualidad de España y Cataluña, está el intento de celebración del referendum, ilegalizado por el tribunal constitucional de España, pero que el gobierno catalán no reconoció. Así comenzó una pugna en la que el gobierno español intentaba frenarlo, y el gobierno catalán intentaba celebrarlo.

No quiero entrar en política, sino en el interesante caso de cómo intentaron resolver desde el gobierno catalán el problema de informar vía web a los ciudadanos dónde tenían que votar. Es una lección de criptografía y redes distribuidas, que considero muy interesante (desde el punto de vista técnico).

Definición del problema

Los métodos tradicionales para informar a la población no se podían utilizar, porque serían automáticamente bloqueados por las fuerzas de seguridad del estado. No se pueden mandar cartas a los ciudadanos, ni acciones similares.

Tampoco se puede publicar directamente el listado a diestro y siniestro, porque se estarían revelando importantes datos de carácter personal. Datos que en manos equivocadas podrían llegar a ser peligrosos.

Así queda planteado el reto: ¿Cómo informar de dónde se tiene que votar utilizando internet de forma masiva y sin revelar la lista completa?

La solución al problema

La solución al problema se basó en dos principios:

  1. Encriptar toda la base de datos de forma que conociendo los datos personales de un ciudadano se pudiese desencriptar sólo la información relativa a donde tenía que votar esa persona.
  2. Distribuir la base de datos, y la aplicación que haría el desencriptado en una red P2P de forma que no se pudiese bloquear su difusión.

De esta manera un usuario podría acceder a la aplicación y usando sus datos personales desencriptar el lugar donde tenía que ir a votar. La solución parece técnicamente perfecta, pero creo que se equivocaron en un par de puntos.

Distribución de la base de datos

Para la distribución de la base de datos y la aplicación, diseñaron una aplicación web, que publicaron en IPFS. IPFS hacía muy complicado cortar la distribución a las fuerzas de seguridad del estado, ya que era un sitio externo. Se podría haber cortado, pero cortando o afectando a todos los servicios publicados en IPFS, algo muy drástico. Incluso cortando ipfs.io, cualquiera que se hubiese descargado el cliente de IPFS, encontraría un peer que replicase la aplicación, ya que IPFS permite que cualquiera replicase el sitio y se convirtiese en proveedor de la aplicación.

De esta manera se resolvió el problema de distribuirlo.

Problema de la distribución

No estoy seguro, pero por lo que he leído IPFS no garantiza el anonimato de aquellos que publican o clonan el contenido por lo que se podría localizar y presentar cargos contra los que hayan colaborado, ya que pueden haber cometido un delito sobre datos personales u otros cargos.

Encriptación de los datos

La encriptación de los datos se hizo de la siguiente manera. Para cada ciudadano se utilizaron los siguientes datos personales:

  • DNI: Sólo se utilizaron los últimos 5 números y la letra
  • Fecha de nacimiento: En formato “YYYYMMDD”
  • Código postal: Cinco números

 

Se concatenan estos valores y se obtiene la clave de cifrado.

A partir de esta clave se calculan dos variables:

  • Contraseña: Como el cálculo de 1714 veces un HASH basado en SHA-256.
  • Índice: Cómo el HASH SHA-256 de la contraseña anterior.

Así, a partir de los datos personales se calcula una contraseña de 256 bits y un índice de 256 bits. Con la contraseña se encriptó el texto del lugar en el que se tenía que ir a votar, lo que resulta en una base de datos que contiene el índice, y el texto encriptado.

Así para desencriptarlo, alguien en posesión de los datos personales, podía calcular el índice y la contraseña. Con el índice podía encontrar el registro, y con la contraseña, desencriptarlo. Por supuesto, esto último lo hacía la aplicación web.

Para no tener que distribuir una gran base de datos con todos los índices, se partió el fichero de datos en 64.000 ficheros. Los 16 primeros bits del índice identificaban el fichero a descargar, y los 240 restantes el índice dentro de ese fichero que había que buscar. Dado que en Cataluña el censo era menor a 6.000.000 de personas, cada fichero contenía en promedio menos de 100 registros.

A priori parece un buen sistema y que cumple con la premisa: Datos personales necesarios para desencriptar el lugar donde votar. Y datos personales encriptados: sólo conociendo los datos, puedes desencriptar. No se puede obtener la lista de datos en limpio. ¿o no?

Problema con la encriptación

El primer error que se comete (desde mi punto de vista) es la longitud de la clave para obtener el HASH, que es muy, muy pequeña. Veamos el tamaño que tiene:

  • DNI: 5 números y una letra (de 23 posibles) hacen 2,3·10^6 combinaciones.
  • Fecha de nacimiento: Asumiendo que no se puede votar con menos de 18 años y descartando mayores de 98, nos quedan 80 años. Por lo tanto hay 80·365=2,9·10^4
  • Código postal: Hay unos 2.000 códigos postales posibles en Cataluña, por lo tanto 2·10^3

Así, combinando todo obtenemos 1,3·10^14, que en bits son menos de 47 bits. Al ser un tamaño muy inferior al de los 256 bits del SHA, la probabilidad de colisión es muy muy baja.

Por lo tanto es posible, por fuerza bruta, repasar todas las posibles combinaciones, calcular 1715 veces su HASH y ver si está en la lista de índices publicados. Esto implica calcular 2,3·10^17 veces la función de Hash. Calcular esto con un PC, puede ser un reto considerable, pero un combo formado por un dispositivo especializado en calcular el HASH, y un PC buscando las coincidencias, podría resolverlo en poco tiempo. Por ejemplo, usando el AntMiner S9 (creo que es el dispositivo para minería de bitcoins más potente del mercado, y que cuesta unos 2.000 €) se pueden procesar 28·10^12 hashes por segundo (14 TH/s, en donde un H, es un double-hash). Así esta maquinita reventaría todas las posibles opciones en menos de 17,000 segundos, unas 5 horas.

Probablemente habría otros retos, pero en cualquier caso, sería algo que un hacker podría resolver con el alquiler de una maquinita de estas unos días.

Por lo tanto es viable obtener el listado completo en abierto de la fracción de DNI, fecha de nacimiento y código postal. Sé que parece poca información, pero en manos equivocadas y cruzada con otras fuentes, puede llegar a ser peligrosa.

Además, el problema se puede simplificar muchísimo si ya tenemos otro dato. Por ejemplo, se puede obtener un DNI por internet (el BOE y otras webs son fuentes de DNI). Sabiendo las 5 cifras y la letra, el problema pasa de una complejidad del orden de 10^17 a 10^11, reduciendo enormemente los tiempos de procesado.

¿Por qué es peligrosa esta información?

Por ejemplo, es fácil obtener DNI por internet, pero no tanto la fecha de nacimiento asociada. Teniendo un DNI y la base de datos abierta anterior se puede obtener una fecha de nacimiento que tiene muchas opciones de ser válida. Luego se puede acceder por ejemplo a ING Direct, que pide como primera prueba el DNI y la fecha de nacimiento, y a continuación un código de 3 cifras (es de 6, pero sólo preguntan 3). Por cada 1000 personas del censo que tengamos su DNI y tengan cuenta en ING Direct, entraremos la gestión bancaria de una de ellas. Y eso asumiendo que sólo nos dejen intentarlo una vez por usuario. ¡Ahora ya no parece información tan trivial! ¿verdad?

Es cierto que una vez dentro no podría hacer transferencias, pero se podría obtener muchísima información, como números de cuenta, saldos, últimos movimientos, números de tarjeta, y con esa información se puede hacer mucho, mucho daño. Y no digamos las opciones de fishing que abre.

Además, incluso sin poder cruzar la información puede ser peligroso. Con las 5 cifras conocidas del DNI, sólo restan 3 por calcular (el DNI español tiene 8 cifras). Así son 1000 opciones. Pero sólo una entre cada 23 será válida, ya que la letra, que la conocemos, es un dígito de control. Así que hay 43 o 44 posibles DNI por cada ciudadano. Por lo que unido esto a las 1000 posibles opciones de la contraseña de ING Direct, tendremos que la base de datos en abierto nos permitirá atacar a ING de forma que uno de cada 50.000 intentos, consiga entrar en la cuenta. Y esto sin cruzar nada más! Si el atacante tiene la habilidad suficiente de hacer el ataque desde múltiples proxies, para que sus intentos fallidos no activen las alarmas de ING, estaríamos delante de un riesgo potencial.

Estoy convencido que en el caso de una entidad como ING, tendrán muchas medidas para evitar un ataque de este tipo. Seguro que detectarían comportamientos anómalos, aumento de actividad o dobles factores de autenticación. Pero sólo quería poner de relieve la importancia de la información que se ha hecho pública y como podría usarse. Seguro que hay otros recursos en Internet que esta información abriría puertas. Y una base de datos tan amplia, seguro que puede dar opciones de ataque a Hackers.

¿Cómo se podría haber evitado?

La solución correcta habría sido ampliar el espacio de texto a cifrar, o ampliar el número de anidado de Hash que han hecho, con el fin de ampliar el coste computacional del descifrado. Pero esto habría traído contras:

  • Ampliar el espacio de texto a cifrar tiene dos implicaciones importantes:
    • Por un lado ampliamos la cantidad de información que quedaría expuesta si se descifrase. Creo que por eso pusieron sólo 5 dígitos y no los 8. 3 dígitos más hubiese ampliado el espacio en 6 bits (ya que la letra es un dígito de control), pero a cambio el secreto desvelado sería muy superior. Y si añadimos más datos, pasaría lo mismo.
    • Por otro aumentamos la posibilidad de que la persona no introduzca correctamente el dato. Por ejemplo, una opción habría sido poner el nombre completo. Esto habría ampliado el espacio del texto enormemente, y no se hubiese podido romper por fuerza bruta. Pero basta que la gente ponga una letra mal de su nombre, un acento que falte, y ya no encontraría su centro donde votar.
  • Aumentar los ciclos de hash haría más costoso el descifrado. Duplicar el valor haría el doble de lenta la operación normal, y afectaría en la misma proporción al tiempo de rotura en fuerza bruta. Por lo tanto no creo que ese hubiese sido el camino.

Por lo tanto lo único que hubiesen podido hacer es aumentar los datos que se pedían, con datos no tan críticos como un DNI, y que seguro que pusiesen bien. Tal vez, el número de la tarjeta de CatSalut (la seguridad social catalana) podría haber sido la solución. Pero… ¿Y la gente sin ese dato? Resumiendo: muy complicado.

Disclaimer

Este artículo lo escribo sin querer levantar ninguna polémica sobre la actual situación. Sólo lo he escrito porque me ha parecido muy interesante el reto que se tenía, como lo han resuelto y los errores que creo que han cometido. Únicamente desde un punto de vista académico y de seguridad.

Por otro lado la información que muestro la he obtenido de Internet de fuentes no demasiado fiables, por lo que puede ser que tenga errores. Si ves alguno, por favor coméntalo.

Sobre el autor

Jose M. Huerta

Jose es Gestor de Proyectos y Gestor de Servicios en Mallorca. Es Ingeniero de Telecomunicaciones y obtuvo el Master of Advanced Studies durante su etapa como investigador. Pero no tardó en abandonar ese mundo y meterse de cabeza en el mundo de las Tecnologías de la Información.
Está certificado como ITIL Expert. Tiene amplia experiencia en gestión de servicios, clásica e integrada con desarrollo, gestión de proyectos, usando metodologías clásicas y ágiles, gestión de programas y portfolios, gestión de grandes grupos de personas, localizadas y off-shore, sin dejar de perder de vista el lado técnico y freak del sector.
Ha trabajado en varias empresas del sector con distintos roles en áreas tanto de gestión de servicios de soporte como de equipos de desarrollo.
Actualmente trabaja en Sunhotels, como responsable del equipo de operaciones TI.

2 comments

  1. Anonimo 18 octubre, 2017 at 23:59 Responder

    > Por cada 1000 personas del censo que tengamos
    > su DNI y tengan cuenta en ING Direct, entraremos
    > la gestión bancaria de una de ellas
    Las posibilidades de acceso son independientes entre personas, es decir, 1 entre 1000 para CADA persona, NO para todo el censo…

    • Jose M. Huerta 19 octubre, 2017 at 06:45 Responder

      Me refiero a estadísticamente, aplicando la ley de los grandes números. Si las posibilidades son 1 entre 1000 por cada persona, significa que estadísticamente por cada 1000 intentos lograremos entrar en una de ellas. Es como en un dado, cada tirada es independiente de la anterior. Hay 1 entre 6 opciones de sacar un 1. Por lo que estadísticamente por cada 6 tiradas que hagamos, lograremos un 1. Si tiramos 600 veces el dado, sacaremos aproximadamente 100 unos. Lo mismo con el censo. Si tenemos 200.000 clientes de ING Direct en el Censo, explotándolo e intentándolo una vez por cliente, nos colaremos en aproximadamente 200 cuentas. Y si nos dejan intentarlo dos veces por cliente, sin que el banco lo note, entraremos en aproximadamente 400. A lo mejor serán 380, o 420; pero será un número cercano a 400.

Post a new comment