| Kriptópolis alojado en |
| Zilos-Veloxia Network |
| Tu mejor defensa: |
| Bufet Almeida |
E-VOTO amateur
Estoy terminando una pequeña plataforma de e-voto y me gustaría compartir su funcionamiento con vosotros, con la esperanza de que me indiquéis qué agujeros o errores le véis, ya que soy una sola persona y la cosa se complica bastante; seguro que encontráis detalles en los que yo no he reparado.
La plataforma es web; existe un servidor en el que se ejecuta y los usuarios entran con su navegador realizando conexiones seguras SSL/TLS (se puede forzar a 128 bits o a sólo TLS, etc). El usuario se autentica en el servidor con certificado, pero no tiene que firmar nada en local, es decir, que no se le instala ningún ActiveX, Applet, ni nada, para garantizar la compatibilidad con navegadores, sistemas operativos, etc. La comprobación de que tiene la clave privada asociada al certificado la hace el SSL/TLS en el Handshake con encadenamiento y firma de dos hash en el caso de TLS. En resumen, que sólo es necesario saber que el que vota es quien dice ser, no hace falta que firme nada...
La plataforma nos permite diseñar la consulta como queramos, pero para no liarlo mucho voy a explicar la configuración tipo de un referéndum, es decir, que los resultados parciales son secretos, que los resultados finales son públicos, y que el acceso de los votantes es “moderado”, o sea que tienes que entrar primero para comprobar que estás censado y después para votar (ya que yo no tengo acceso a la bbdd del censo).
Cada referéndum tiene una tabla de Timestamp; esto significa que todos los votos realizados tendrán su correspondencia en dicha tabla pública mediante encadenamientos de hash, para garantizar la no inserción de votos. En dicha tabla hay una relación entre el hash del Timestamp y la clave pública del votante, pero NO con la intención de voto.
El autor del referéndum tiene que identificarse con un certificado a la hora de crearlo, ya que el servidor necesita su clave pública para cifrar datos y para garantizar que sólo él tiene acceso al panel de control de su referéndum. Todos los datos que se almacenan en bbdd son cifrados, unos con la clave pública del certificado del autor, otros con la pública del certificado del votante, y otros con la pública del certificado del servidor (ya veremos más adelante cuáles con una y cuáles con otra). Una vez creado el referéndum, el autor tiene acceso a su panel de control, en el que puede hacer modificaciones hasta el momento en que se abra la urna electrónica. Llegado este momento los votantes tienen acceso a la urna y éste es el proceso que se sigue:
El usuario se identifica con su certificado estableciendo una conexión segura (cifrada) con el servidor, el cual guarda en bbdd una copia del certificado (sin clave privada claro) cifrándola con el certificado del servidor (para garantizar la protección de datos, etc). En este momento es cuando en el panel de control del autor se le van mostrando al moderador los usuarios que solicitan permiso para votar y es cuando se debería cotejar el censo (también se puede discriminar por campos del certificado, CA’s, por claves, etc). Por supuesto el moderador se ha tenido que identificar con su certificado y el servidor está descifrando y mostrando la información en tiempo real. Una vez concedido el permiso, el usuario tiene acceso a la votación. Se le muestran las opciones que tiene (aquí se me ha olvidado meter el voto en blanco pero estoy en ello) y, una vez seleccionada pulsa en “Votar”. El server genera una clave aleatoria de 128 bits, y al final de dicha clave, suma la intención de voto. Esto lo hago para que no se pueda deducir la intención de voto por consulta a tablas de hash, es decir que si yo guardo sólo la intención de voto, PP, por ejemplo, sólo con comparar el hash de la bbdd con el hash de las opciones, sabría quién ha votado a quién, además todos los votos a la misma opción tendrían el mismo hash. Después el server saca el hash de la papeleta, el hash del Timestamp y hace dos cifrados de la papeleta, uno con el certificado del votante y otro con el certificado del autor del referéndum. El hash del Timestamp, la clave pública del certificado del votante, y la papeleta cifrada con el certificado del votante lo encadena y guarda en la tabla de Timestamp, y el hash de la papeleta y la papeleta cifrada con el certificado del autor del referéndum la guarda en la tabla “votos” que tiene un ID aleatorio para que no se puedan relacionar entradas en las dos tablas por ningún orden.
Una vez finalizado el plazo de votación, la urna se cierra y le aparece al autor del referéndum la opción de “recuento” en su panel de control. En este proceso, el servidor le manda las papeletas cifradas con su clave pública a su navegador (aquí sí que he tenido que exigir IE; si alguien conoce alguna función Javascript tipo crypto.signText pero para descifrar en otros navegadores, que me lo comunique por favor) y, el autor del referéndum las descifra con su certificado, mostrándole el resultado en local (Jscript). Si lo desea puede pedir comprobación de "No manipulación" al server, en cuyo caso se mandan las papeletas descifradas al servidor (recordar que seguimos bajo SSL/TLS) para generar sus hash y cotejarlos con los hash de la tabla “Votos”, pero esto es opcional. Después se guarda el total computado en el server para mostrar gráficos de resultados finales, etc.
Durante, y una vez finalizada la votación, cualquier votante puede auditar su voto identificándose en el server con su certificado, y descifrando su papeleta (la copia cifrada con su pública de la tabla “Timestamp”) así como comprobando el encadenamiento del mismo.
Cada script tiene una rutina que genera un par de hash del propio archivo que se esté ejecutando. Este script también se puede ejecutar en otros servidores que auditen en tiempo real la no modificación del código durante la votación. Lógicamente, si se trata de algo serio se tendría que hacer una primera auditoría del código para asegurar que no se guardan la papeletas sin cifrar, etc. Además el servidor sólo tiene abierto el puerto 443 (https) y dos usuarios, el invitado para la web (con sus permisos paupérrimos) y el Administrador al que se le exige inicio de sesión con tarjeta criptográfica (certificado).
Bueno, más o menos sería así. Nótese que, en el caso aquí explicado (ya comenté que la plataforma es configurable), el server no puede descifrar las papeletas, el autor puede descifrarlas pero no puede saber a quién pertenecen (ya que en la tabla de Timestamp no hay hash de la papeleta, no hay relación entre tablas) y el votante sólo puede descifrar su papeleta a la hora de auditar el proceso, autentificándose con su certificado que le llevará a su Timestamp, y descifrando su papeleta en local con su clave privada. Además, ni siquiera el robo de los discos duros del server implicarían el robo de datos, ya que todo se encuentra cifrado con las claves públicas de los usuarios (cuyas claves privadas están en sus equipos) y la pública del server (que se encuentra en un dispositivo criptográfico externo). De ahí un poco la independencia del sistema operativo que use en el server; otra cosa son los ataques por denegación de servicio, etc, pero mis recursos son limitados. Además la modificación del código una vez pasada la primera auditoría haría cambiar el hash de los archivos (esto no quiere decir que no se puedan hacer cambios, sólo que no se pueden hacer injustificados).
No seáis muy duros conmigo, que ya os he comentado que sólo soy yo para montar todo el tinglado (y de forma altruista), y me he tirado casi un mes partiéndome los cuernos con el proyectito.
Un cordial saludo,
Enriquez
PD: Cuando me refiero a hash, estoy hablando siempre de encadenamiento de distintos algoritmos hash por el tema de las colisiones.




Opinar